From 9dc7bc000c20f10f28af0dc892f8e50c802abf92 Mon Sep 17 00:00:00 2001
From: RIHTARSIC Joze <joze.rihtarsic@ext.ec.europa.eu>
Date: Thu, 4 May 2023 07:19:21 +0200
Subject: [PATCH] Add unit tests

---
 .../ec/edelivery/smp/data/dao/UserDao.java    |  99 +---------
 .../data/model/DBDomainDeleteValidation.java  |  44 -----
 .../smp/services/ServiceMetadataService.java  | 171 ------------------
 .../config/SmlIntegrationConfiguration.java   |  22 +--
 .../smp/data/dao/AbstractResourceDaoTest.java |   4 +
 .../smp/data/dao/AlertDaoIntegrationTest.java |   1 -
 .../smp/data/dao/AuditIntegrationTest.java    |   2 +-
 .../edelivery/smp/data/dao/BaseDaoTest.java   |   1 -
 .../ResourceDaoMembershipIntegrationTest.java |  76 ++++++++
 ...rviceGroupDaoOwnershipIntegrationTest.java | 128 -------------
 .../smp/data/dao/UserDaoIntegrationTest.java  | 137 +++++++-------
 .../AbstractServiceIntegrationTest.java       |   2 +-
 ...nticationByClientCertFromKeystoreTest.java |  48 ++---
 .../smp/sml/SmlConnectorDomainTest.java       |   7 +-
 .../edelivery/smp/testutil/TestDBUtils.java   |  10 +-
 .../smp-keystore_multiple_domains.jks         | Bin 3451 -> 5571 bytes
 16 files changed, 189 insertions(+), 563 deletions(-)
 delete mode 100644 smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBDomainDeleteValidation.java
 delete mode 100644 smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ServiceMetadataService.java
 create mode 100644 smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ResourceDaoMembershipIntegrationTest.java
 delete mode 100644 smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ServiceGroupDaoOwnershipIntegrationTest.java

diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/UserDao.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/UserDao.java
index 23615e6ed..8efd03184 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/UserDao.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/UserDao.java
@@ -16,7 +16,6 @@ package eu.europa.ec.edelivery.smp.data.dao;
 import eu.europa.ec.edelivery.smp.data.enums.CredentialTargetType;
 import eu.europa.ec.edelivery.smp.data.enums.CredentialType;
 import eu.europa.ec.edelivery.smp.data.model.DBUserDeleteValidation;
-import eu.europa.ec.edelivery.smp.data.model.user.DBCredential;
 import eu.europa.ec.edelivery.smp.data.model.user.DBUser;
 import eu.europa.ec.edelivery.smp.exceptions.SMPRuntimeException;
 import eu.europa.ec.edelivery.smp.logging.SMPLogger;
@@ -28,12 +27,12 @@ import javax.persistence.NoResultException;
 import javax.persistence.NonUniqueResultException;
 import javax.persistence.TypedQuery;
 import javax.transaction.Transactional;
-import java.time.OffsetDateTime;
 import java.util.List;
 import java.util.Optional;
 
 import static eu.europa.ec.edelivery.smp.data.dao.QueryNames.*;
 import static eu.europa.ec.edelivery.smp.exceptions.ErrorCode.ILLEGAL_STATE_USERNAME_MULTIPLE_ENTRY;
+import static eu.europa.ec.edelivery.smp.exceptions.ErrorCode.INVALID_USER_NO_IDENTIFIERS;
 
 /**
  * @author gutowpa
@@ -42,10 +41,6 @@ import static eu.europa.ec.edelivery.smp.exceptions.ErrorCode.ILLEGAL_STATE_USER
 @Repository
 public class UserDao extends BaseDao<DBUser> {
     private static final SMPLogger LOG = SMPLoggerFactory.getLogger(UserDao.class);
-    private static final String QUERY_PARAM_ALERT_CREDENTIAL_START_DATE = "startAlertDate";
-    private static final String QUERY_PARAM_ALERT_CREDENTIAL_END_DATE = "endAlertDate";
-    private static final String QUERY_PARAM_ALERT_CREDENTIAL_EXPIRE_DATE = "expireDate";
-    private static final String QUERY_PARAM_ALERT_CREDENTIAL_LAST_ALERT_DATE = "lastSendAlertDate";
 
 
     /**
@@ -57,9 +52,10 @@ public class UserDao extends BaseDao<DBUser> {
     @Transactional
     public void persistFlushDetach(DBUser user) {
         // update username to lower caps
-        if (!StringUtils.isBlank(user.getUsername())) {
-            user.setUsername(user.getUsername().toLowerCase());
+        if (StringUtils.isBlank(user.getUsername())) {
+            throw new SMPRuntimeException(INVALID_USER_NO_IDENTIFIERS);
         }
+        user.setUsername(user.getUsername().toLowerCase());
         super.persistFlushDetach(user);
     }
 
@@ -201,90 +197,7 @@ public class UserDao extends BaseDao<DBUser> {
             throw new SMPRuntimeException(ILLEGAL_STATE_USERNAME_MULTIPLE_ENTRY, username);
         }
     }
-/*
-    public List<DBUser> getBeforePasswordExpireUsersForAlerts(int beforeStartDays, int alertInterval, int maxAlertsInBatch) {
-        OffsetDateTime expireDate = OffsetDateTime.now();
-        OffsetDateTime startDateTime = expireDate.plusDays(beforeStartDays);
-        OffsetDateTime lastSendAlertDate = expireDate.minusDays(alertInterval);
-
-        TypedQuery<DBUser> query = memEManager.createNamedQuery(QUERY_USER_BEFORE_PASSWORD_EXPIRE, DBUser.class);
-        query.setParameter(PARAM_CREDENTIAL_TYPE, CredentialType.USERNAME_PASSWORD );
-        query.setParameter(QUERY_PARAM_ALERT_CREDENTIAL_START_DATE, startDateTime);
-        query.setParameter(QUERY_PARAM_ALERT_CREDENTIAL_EXPIRE_DATE, expireDate);
-        query.setParameter(QUERY_PARAM_ALERT_CREDENTIAL_LAST_ALERT_DATE, lastSendAlertDate);
-        query.setMaxResults(maxAlertsInBatch);
-        return query.getResultList();
-    }
-
-    public List<DBUser> getPasswordExpiredUsersForAlerts(int alertPeriodDays, int alertInterval, int maxAlertsInBatch) {
-        OffsetDateTime expireDate = OffsetDateTime.now();
-        // the alert period must be less then expire day
-        OffsetDateTime startDateTime = expireDate.minusDays(alertPeriodDays);
-        OffsetDateTime lastSendAlertDate = expireDate.minusDays(alertInterval);
-
-        TypedQuery<DBUser> query = memEManager.createNamedQuery(QUERY_USER_WITH_PASSWORD_EXPIRED, DBUser.class);
-        query.setParameter(PARAM_CREDENTIAL_TYPE, CredentialType.USERNAME_PASSWORD );
-        query.setParameter(QUERY_PARAM_ALERT_CREDENTIAL_END_DATE, startDateTime);
-        query.setParameter(QUERY_PARAM_ALERT_CREDENTIAL_EXPIRE_DATE, expireDate);
-        query.setParameter(QUERY_PARAM_ALERT_CREDENTIAL_LAST_ALERT_DATE, lastSendAlertDate);
-        query.setMaxResults(maxAlertsInBatch);
-        return query.getResultList();
-    }
-
-    public List<DBUser> getBeforeAccessTokenExpireUsersForAlerts(int beforeStartDays, int alertInterval, int maxAlertsInBatch) {
-        OffsetDateTime expireDate = OffsetDateTime.now();
-        OffsetDateTime startDateTime = expireDate.plusDays(beforeStartDays);
-        OffsetDateTime lastSendAlertDate = expireDate.minusDays(alertInterval);
-
-        TypedQuery<DBUser> query = memEManager.createNamedQuery("DBUser.getUsersForBeforeAccessTokenExpireAlerts", DBUser.class);
-        query.setParameter(QUERY_PARAM_ALERT_CREDENTIAL_START_DATE, startDateTime);
-        query.setParameter(QUERY_PARAM_ALERT_CREDENTIAL_EXPIRE_DATE, expireDate);
-        query.setParameter(QUERY_PARAM_ALERT_CREDENTIAL_LAST_ALERT_DATE, lastSendAlertDate);
-        query.setMaxResults(maxAlertsInBatch);
-        return query.getResultList();
-    }
 
-    public List<DBUser> getAccessTokenExpiredUsersForAlerts(int alertPeriodDays, int alertInterval, int maxAlertsInBatch) {
-        OffsetDateTime expireDate = OffsetDateTime.now();
-        // the alert period must be less then expire day
-        OffsetDateTime startDateTime = expireDate.minusDays(alertPeriodDays);
-        OffsetDateTime lastSendAlertDate = expireDate.minusDays(alertInterval);
-
-        TypedQuery<DBUser> query = memEManager.createNamedQuery("DBUser.getUsersForAccessTokenExpiredAlerts", DBUser.class);
-        query.setParameter(QUERY_PARAM_ALERT_CREDENTIAL_END_DATE, startDateTime);
-        query.setParameter(QUERY_PARAM_ALERT_CREDENTIAL_EXPIRE_DATE, expireDate);
-        query.setParameter(QUERY_PARAM_ALERT_CREDENTIAL_LAST_ALERT_DATE, lastSendAlertDate);
-        query.setMaxResults(maxAlertsInBatch);
-        return query.getResultList();
-    }
-
-    public List<DBUser> getBeforeCertificateExpireUsersForAlerts(int beforeStartDays, int alertInterval, int maxAlertsInBatch) {
-        OffsetDateTime expireDate = OffsetDateTime.now();
-        OffsetDateTime startDateTime = expireDate.plusDays(beforeStartDays);
-        OffsetDateTime lastSendAlertDate = expireDate.minusDays(alertInterval);
-
-        TypedQuery<DBUser> query = memEManager.createNamedQuery("DBUser.getUsersForBeforeCertificateExpireAlerts", DBUser.class);
-        query.setParameter(QUERY_PARAM_ALERT_CREDENTIAL_START_DATE, startDateTime);
-        query.setParameter(QUERY_PARAM_ALERT_CREDENTIAL_EXPIRE_DATE, expireDate);
-        query.setParameter(QUERY_PARAM_ALERT_CREDENTIAL_LAST_ALERT_DATE, lastSendAlertDate);
-        query.setMaxResults(maxAlertsInBatch);
-        return query.getResultList();
-    }
-
-    public List<DBUser> getCertificateExpiredUsersForAlerts(int alertPeriodDays, int alertInterval, int maxAlertsInBatch) {
-        OffsetDateTime expireDate = OffsetDateTime.now();
-        // the alert period must be less then expire day
-        OffsetDateTime startDateTime = expireDate.minusDays(alertPeriodDays);
-        OffsetDateTime lastSendAlertDate = expireDate.minusDays(alertInterval);
-
-        TypedQuery<DBUser> query = memEManager.createNamedQuery("DBUser.getUsersForCertificateExpiredAlerts", DBUser.class);
-        query.setParameter(QUERY_PARAM_ALERT_CREDENTIAL_END_DATE, startDateTime);
-        query.setParameter(QUERY_PARAM_ALERT_CREDENTIAL_EXPIRE_DATE, expireDate);
-        query.setParameter(QUERY_PARAM_ALERT_CREDENTIAL_LAST_ALERT_DATE, lastSendAlertDate);
-        query.setMaxResults(maxAlertsInBatch);
-        return query.getResultList();
-    }
-*/
     /**
      * Validation report for users which owns service group
      *
@@ -310,7 +223,7 @@ public class UserDao extends BaseDao<DBUser> {
             query.setMaxResults(iPageSize);
         }
         if (hasFilter) {
-            query.setParameter(PARAM_USER_FILTER, StringUtils.wrapIfMissing(StringUtils.trim(filter),"%" ));
+            query.setParameter(PARAM_USER_FILTER, StringUtils.wrapIfMissing(StringUtils.trim(filter), "%"));
         }
         return query.getResultList();
     }
@@ -319,7 +232,7 @@ public class UserDao extends BaseDao<DBUser> {
         boolean hasFilter = StringUtils.isNotBlank(filter);
         TypedQuery<Long> query = memEManager.createNamedQuery(hasFilter ? QUERY_USER_FILTER_COUNT : QUERY_USER_COUNT, Long.class);
         if (hasFilter) {
-            query.setParameter(PARAM_USER_FILTER, StringUtils.wrapIfMissing(StringUtils.trim(filter),"%" ));
+            query.setParameter(PARAM_USER_FILTER, StringUtils.wrapIfMissing(StringUtils.trim(filter), "%"));
         }
         return query.getSingleResult();
     }
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBDomainDeleteValidation.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBDomainDeleteValidation.java
deleted file mode 100644
index 40f8d55de..000000000
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBDomainDeleteValidation.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package eu.europa.ec.edelivery.smp.data.model;
-
-
-public class DBDomainDeleteValidation {
-
-    Long id;
-    String domainCode;
-    String smlSubdomain;
-    Integer count;
-
-    public DBDomainDeleteValidation() {
-    }
-
-    public DBDomainDeleteValidation(Long id, String domainCode, String smlSubdomain,  Integer count) {
-        this.id = id;
-        this.domainCode = domainCode;
-        this.smlSubdomain = smlSubdomain;
-        this.count = count;
-    }
-
-    public Long getId() {
-        return id;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
-
-    public String getDomainCode() {
-        return domainCode;
-    }
-
-    public void setDomainCode(String domainCode) {
-        this.domainCode = domainCode;
-    }
-
-    public Integer getCount() {
-        return count;
-    }
-
-    public void setCount(Integer count) {
-        this.count = count;
-    }
-}
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ServiceMetadataService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ServiceMetadataService.java
deleted file mode 100644
index 425fa5acb..000000000
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ServiceMetadataService.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright 2017 European Commission | CEF eDelivery
- *
- * 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 attached in file: LICENCE-EUPL-v1.2.pdf
- *
- * 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.
- */
-
-package eu.europa.ec.edelivery.smp.services;
-
-import eu.europa.ec.edelivery.smp.conversion.IdentifierService;
-import eu.europa.ec.edelivery.smp.data.dao.ResourceDao;
-import eu.europa.ec.edelivery.smp.data.dao.SubresourceDao;
-import eu.europa.ec.edelivery.smp.identifiers.Identifier;
-import eu.europa.ec.edelivery.smp.services.spi.SmpXmlSignatureService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import org.w3c.dom.Document;
-
-import java.util.Collections;
-import java.util.List;
-
-
-/**
- * Created by gutowpa on 14/11/2017.
- */
-@Service
-public class ServiceMetadataService {
-
-    @Autowired
-    private IdentifierService identifierService;
-
-    @Autowired
-    private SubresourceDao serviceMetadataDao;
-
-    @Autowired
-    private ResourceDao serviceGroupDao;
-
-    @Autowired
-    private DomainService domainService;
-
-    @Autowired
-    private SmpXmlSignatureService signer;
-
-
-    @Transactional
-    public Document getServiceMetadataDocument(Identifier serviceGroupId, Identifier documentId) {
-/*
-        Identifier normalizedServiceGroupId = identifierService.normalizeParticipant(serviceGroupId);
-        Identifier normalizedDocId = identifierService.normalizeDocument(documentId);
-
-        Optional<DBSubresource> osmd = serviceMetadataDao.findServiceMetadata(normalizedServiceGroupId.getValue(),
-                normalizedServiceGroupId.getScheme(),normalizedDocId.getValue(),normalizedDocId.getScheme());
-
-
-        if (!osmd.isPresent() || osmd.get().getXmlContent() == null) {
-            throw new SMPRuntimeException(METADATA_NOT_EXISTS,normalizedServiceGroupId.getValue(),
-                    normalizedServiceGroupId.getScheme(),normalizedDocId.getValue(),normalizedDocId.getScheme());
-        }
-        DBSubresource smd = osmd.get();
-
-        Document signedServiceMetadata = toSignedServiceMetadataDocument(smd.getXmlContent());
-        DBDomain resourceDomain = smd.getResource().getDomainResourceDef().getDomain();
-        String sigCertAlias = resourceDomain.getSignatureKeyAlias();
-        String signatureAlgorithm = resourceDomain.getSignatureAlgorithm();
-        String signatureDigestMethod = resourceDomain.getSignatureDigestMethod();
-
-        signer.sign(signedServiceMetadata, sigCertAlias, signatureAlgorithm,signatureDigestMethod );
-        return signedServiceMetadata;
-
- */
-        return null;
-    }
-
-    /**
-     * Creates or updates ServiceMetadata
-     *
-     * @return True if new ServiceMetadata was created. False if existing one was updated.
-     */
-    @Transactional
-    public boolean saveServiceMetadata(String domain, Identifier serviceGroupId, Identifier documentId, byte[] xmlContent) {
-/*
-        Identifier normalizedServiceGroupId = identifierService.normalizeParticipant(serviceGroupId);
-        Identifier normalizedDocId = identifierService.normalizeDocument(documentId);
-
-        Optional<DBResource> serviceGroup = serviceGroupDao.findServiceGroup(normalizedServiceGroupId.getValue(),
-                normalizedServiceGroupId.getScheme());
-        if (!serviceGroup.isPresent()) {
-            throw new SMPRuntimeException(SG_NOT_EXISTS, normalizedServiceGroupId.getValue(),
-                    normalizedServiceGroupId.getScheme());
-        }
-        //test and retrieve domain
-        DBDomain dbDomain = domainService.getDomain(domain);
-
-        Optional<DBSubresource> doc =  serviceMetadataDao.findServiceMetadata(normalizedServiceGroupId.getValue(),
-                normalizedServiceGroupId.getScheme(), normalizedDocId.getValue(), normalizedDocId.getScheme());
-
-        boolean alreadyExisted;
-        if (doc.isPresent()){
-            DBSubresource smd = doc.get();
-            smd.setXmlContent(xmlContent);
-            serviceMetadataDao.update(smd);
-            alreadyExisted = true;
-        } else {
-            DBResource sg = serviceGroup.get();
-            DBSubresource smd = new DBSubresource();
-            smd.setDocumentIdentifier(normalizedDocId.getValue());
-            smd.setDocumentIdentifierScheme(normalizedDocId.getScheme());
-            smd.setXmlContent(xmlContent);
-            Optional<DBDomainResourceDef> osgd =  sg.getServiceGroupForDomain(domain);
-            DBDomainResourceDef sgd = osgd.isPresent()?osgd.get(): sg.addDomain(dbDomain);
-            sgd.addServiceMetadata(smd);
-            serviceGroupDao.update(sg);
-            alreadyExisted = false;
-        }
-
-        return !alreadyExisted;
-
- */
-        return  false;
-
-    }
-
-    @Transactional
-    public void deleteServiceMetadata(String domain, Identifier serviceGroupId, Identifier documentId) {
-/*
-        ParticipantIdentifierType normalizedServiceGroupId = identifierService.normalizeParticipant(serviceGroupId);
-        DocumentIdentifier normalizedDocId = identifierService.normalizeDocument(documentId);
-
-
-        Optional<DBSubresource> oDoc = serviceMetadataDao.findServiceMetadata(normalizedServiceGroupId.getValue(),
-                normalizedServiceGroupId.getScheme(), normalizedDocId.getValue(), normalizedDocId.getScheme());
-        if (!oDoc.isPresent()){
-            throw new SMPRuntimeException(METADATA_NOT_EXISTS,normalizedServiceGroupId.getValue(),
-                    normalizedServiceGroupId.getScheme(),normalizedDocId.getValue(),normalizedDocId.getScheme());
-        }
-        DBSubresource doc = oDoc.get();
-        DBDomainResourceDef sgd = doc.getServiceGroupDomain();
-        sgd.removeServiceMetadata(doc);
-        serviceGroupDao.update(sgd.getServiceGroup());
-
- */
-    }
-
-    public List<Identifier> findServiceMetadataIdentifiers(Identifier participantId) {
-/*
-        Identifier normalizedServiceGroupId = identifierService.normalizeParticipant(participantId);
-        List<DBSubresource> metadata = serviceMetadataDao.getAllMetadataForServiceGroup(
-                normalizedServiceGroupId.getValue(),
-                normalizedServiceGroupId.getScheme());
-
-        List<Identifier> documentIds = new ArrayList<>();
-        for (DBSubresource md : metadata) {
-            Identifier documentIdentifier = new Identifier(md.getIdentifierValue(),
-                    md.getIdentifierScheme());
-            documentIds.add(documentIdentifier);
-        }
-        return documentIds;
-
- */
-        return Collections.emptyList();
-    }
-
-
-}
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/SmlIntegrationConfiguration.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/SmlIntegrationConfiguration.java
index 684d5766c..4edf6b066 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/SmlIntegrationConfiguration.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/SmlIntegrationConfiguration.java
@@ -6,6 +6,7 @@ import org.mockito.ArgumentMatchers;
 import org.mockito.BDDMockito;
 import org.mockito.Mockito;
 import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Primary;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Component;
 
@@ -23,8 +24,6 @@ import static org.springframework.beans.factory.config.ConfigurableBeanFactory.S
 @Component
 public class SmlIntegrationConfiguration {
 
-    //protected final ParticipantIdentifierType PARTICIPANT_ID = new ParticipantIdentifierType("sample:value", "sample:scheme");
-
     protected DBDomain defaultDomain;
 
 
@@ -54,9 +53,10 @@ public class SmlIntegrationConfiguration {
         setThrowException(null);
     }
 
-    @Bean
+    @Bean("MockIManageServiceMetadataWS")
+    @Primary
     @Scope(SCOPE_PROTOTYPE)
-    public IManageServiceMetadataWS smpManagerClient(String clientKeyAlias, String clientCertHttpHeader, boolean authClientCert) throws BadRequestFault, UnauthorizedFault, InternalErrorFault, NotFoundFault {
+    public IManageServiceMetadataWS smpManagerClient() throws BadRequestFault, UnauthorizedFault, InternalErrorFault, NotFoundFault {
 
 
 
@@ -69,16 +69,14 @@ public class SmlIntegrationConfiguration {
         }
 
         AuthenticationTestDataHolder dh = new AuthenticationTestDataHolder();
-        dh.setAlias(clientKeyAlias);
-        dh.setClientCertHeader(clientCertHttpHeader);
         smpManagerClientMocks.add(clientMock);
         smpManagerClientMocksData.put(clientMock, dh);
         return clientMock;
     }
 
-    @Bean
+    @Bean("MockIManageParticipantIdentifierWS")
     @Scope(SCOPE_PROTOTYPE)
-    public IManageParticipantIdentifierWS smpParticipantClient(String clientKeyAlias, String clientCertHttpHeader,boolean authClientCert) throws UnauthorizedFault, NotFoundFault, InternalErrorFault, BadRequestFault {
+    public IManageParticipantIdentifierWS smpParticipantClient() throws UnauthorizedFault, NotFoundFault, InternalErrorFault, BadRequestFault {
 
 
         if (throwExceptionAfterParticipantCallCount >0 &&  throwExceptionAfterParticipantCallCount  <= smlClientMocks.size()){
@@ -97,19 +95,11 @@ public class SmlIntegrationConfiguration {
 
 
         AuthenticationTestDataHolder dh = new AuthenticationTestDataHolder();
-        dh.setAlias(clientKeyAlias);
-        dh.setClientCertHeader(clientCertHttpHeader);
         smlClientMocks.add(clientMock);
         smlClientMocksData.put(clientMock, dh);
         return clientMock;
     }
 
-
-
-    public DBDomain getDefaultDomain() {
-        return defaultDomain;
-    }
-
     public List<IManageServiceMetadataWS> getSmpManagerClientMocks() {
         return smpManagerClientMocks;
     }
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/AbstractResourceDaoTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/AbstractResourceDaoTest.java
index 62fe4020e..d27b6aaf6 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/AbstractResourceDaoTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/AbstractResourceDaoTest.java
@@ -41,9 +41,13 @@ public abstract class AbstractResourceDaoTest extends AbstractBaseDao {
     @Autowired
     UserDao userDao;
 
+    @Autowired
+    ResourceMemberDao resourceMemberDao;
+
 
     @Before
     public void prepareDatabase() {
+        testUtilsDao.clearData();
         // setup initial data!
         testUtilsDao.createResourceDefinitionsForDomains();
         testUtilsDao.createGroups();
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/AlertDaoIntegrationTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/AlertDaoIntegrationTest.java
index fac550aac..a1d25f409 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/AlertDaoIntegrationTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/AlertDaoIntegrationTest.java
@@ -8,7 +8,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 
 import static org.junit.Assert.*;
 
-@Ignore
 public class AlertDaoIntegrationTest extends AbstractBaseDao {
 
     @Autowired
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/AuditIntegrationTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/AuditIntegrationTest.java
index 1f0fc7856..10059d247 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/AuditIntegrationTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/AuditIntegrationTest.java
@@ -104,7 +104,7 @@ public class AuditIntegrationTest extends AbstractBaseDao{
         DBUser user = createDBUser("Credential-test");
         persist(user);
 
-        DBCredential dbCredential = createDBCredential();
+        DBCredential dbCredential = createDBCredential("test");
         dbCredential.setUser(user);
         Map<String, Object> alterVal = new HashMap<>();
         alterVal.put("name", UUID.randomUUID().toString());
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/BaseDaoTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/BaseDaoTest.java
index ecbf55752..fde66a67f 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/BaseDaoTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/BaseDaoTest.java
@@ -22,7 +22,6 @@ import java.util.List;
  * @author Joze Rihtarsic
  * @since 4.1
  */
-@Ignore
 public class BaseDaoTest extends AbstractBaseDao {
 
 
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ResourceDaoMembershipIntegrationTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ResourceDaoMembershipIntegrationTest.java
new file mode 100644
index 000000000..dfe2bc7b9
--- /dev/null
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ResourceDaoMembershipIntegrationTest.java
@@ -0,0 +1,76 @@
+package eu.europa.ec.edelivery.smp.data.dao;
+
+import eu.europa.ec.edelivery.smp.data.enums.MembershipRoleType;
+import eu.europa.ec.edelivery.smp.data.model.doc.DBResource;
+import eu.europa.ec.edelivery.smp.data.model.user.DBResourceMember;
+import eu.europa.ec.edelivery.smp.data.model.user.DBUser;
+import eu.europa.ec.edelivery.smp.testutil.TestConstants;
+import org.junit.Test;
+
+import javax.transaction.Transactional;
+import java.util.Optional;
+
+import static org.junit.Assert.*;
+
+
+/**
+ * Purpose of class is to test all resource methods with database.
+ *
+ * @author Joze Rihtarsic
+ * @since 4.1
+ */
+public class ResourceDaoMembershipIntegrationTest extends AbstractResourceDaoTest {
+
+    @Test
+    @Transactional
+    public void persistNewResourceWithMember() {
+        DBResource resource = createResourceWithMembers(TestConstants.USERNAME_1);
+
+        Optional<DBResource> res = testInstance.findServiceGroup(resource.getIdentifierValue(), resource.getIdentifierScheme());
+        assertTrue(res.isPresent());
+        assertNotSame(resource, res.get());
+        assertEquals(resource, res.get());
+        assertEquals(1, res.get().getMembers().size());
+        assertEquals(TestConstants.USERNAME_1, res.get().getMembers().get(0).getUser().getUsername());
+    }
+
+    @Test
+    @Transactional
+    public void addTwoMembersToServiceGroup() {
+        DBResource resource = createResourceWithMembers(TestConstants.USERNAME_1, TestConstants.USERNAME_3);
+
+        Optional<DBResource> res = testInstance.findServiceGroup(resource.getIdentifierValue(), resource.getIdentifierScheme());
+        assertTrue(res.isPresent());
+        assertEquals(2, res.get().getMembers().size());
+    }
+
+    @Test
+    @Transactional
+    public void removeMemberFromResource() {
+        DBResource resource = createResourceWithMembers(TestConstants.USERNAME_1, TestConstants.USERNAME_3);
+        assertEquals(2, resource.getMembers().size());
+
+        DBResourceMember resourceMember = resource.getMembers().get(0);
+
+        // when
+        boolean result = resourceMemberDao.removeById(resourceMember.getId());
+
+        assertTrue(result);
+
+    }
+
+    public DBResource createResourceWithMembers(String... usernames) {
+        DBResource resource = createAndSaveNewResource();
+        assertTrue(resource.getMembers().isEmpty());
+        for (String username : usernames) {
+            Optional<DBUser> user = userDao.findUserByUsername(username);
+            DBResourceMember member = testUtilsDao.createResourceMembership(MembershipRoleType.ADMIN, user.get(), resource);
+            resourceMemberDao.persistFlushDetach(member);
+            resource.getMembers().add(member);
+        }
+
+        testInstance.clearPersistenceContext();
+        return resource;
+    }
+
+}
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ServiceGroupDaoOwnershipIntegrationTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ServiceGroupDaoOwnershipIntegrationTest.java
deleted file mode 100644
index a9eaeb68f..000000000
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ServiceGroupDaoOwnershipIntegrationTest.java
+++ /dev/null
@@ -1,128 +0,0 @@
-package eu.europa.ec.edelivery.smp.data.dao;
-
-import eu.europa.ec.edelivery.smp.data.model.doc.DBResource;
-import eu.europa.ec.edelivery.smp.data.model.user.DBUser;
-import eu.europa.ec.edelivery.smp.testutil.TestConstants;
-import eu.europa.ec.edelivery.smp.testutil.TestDBUtils;
-import org.junit.Ignore;
-import org.junit.Test;
-
-import javax.transaction.Transactional;
-import java.util.Optional;
-
-import static eu.europa.ec.edelivery.smp.testutil.TestConstants.TEST_SG_ID_1;
-import static eu.europa.ec.edelivery.smp.testutil.TestConstants.TEST_SG_SCHEMA_1;
-import static org.junit.Assert.*;
-
-
-/**
- *  Purpose of class is to test all resource methods with database.
- *
- * @author Joze Rihtarsic
- * @since 4.1
- */
-@Ignore
-public class ServiceGroupDaoOwnershipIntegrationTest extends AbstractResourceDaoTest {
-
-    @Test
-    @Transactional
-    public void persistNewServiceGroupWithOwner() {
-        Optional<DBUser> u1 = userDao.findUserByUsername(TestConstants.USERNAME_1);
-        DBResource sg =TestDBUtils.createDBResource(TEST_SG_ID_1, TEST_SG_SCHEMA_1);
-
-       // sg.getUsers().add(u1.get());
-
-        testInstance.persistFlushDetach(sg);
-        testInstance.clearPersistenceContext();
-
-        Optional<DBResource> res = testInstance.findServiceGroup(TEST_SG_ID_1, TEST_SG_SCHEMA_1);
-        assertTrue(res.isPresent());
-        assertTrue(sg!=res.get());
-        assertEquals(sg, res.get());
-       // assertEquals(1, res.get().getUsers().size());
-        // assertEquals(u1.get(), res.get().getUsers().toArray()[0]);
-    }
-/*
-    @Test
-    @Transactional
-    public void mergeServiceGroupWithOwner() {
-        DBResource o = createAndSaveNewServiceGroup();
-        Optional<DBUser> u3 = userDao.findUserByUsername(TestConstants.USERNAME_3);
-        Optional<DBResource> osg = testInstance.findServiceGroup(o.getIdentifierValue(), o.getIdentifierScheme());
-        DBResource sg = osg.get();
-        assertEquals(0, sg.getUsers().size());
-        assertFalse(sg.getUsers().contains(u3.get()));
-
-        sg.getUsers().add(u3.get());
-
-        testInstance.update(sg);
-        testInstance.clearPersistenceContext();
-
-        Optional<DBResource> res = testInstance.findServiceGroup(o.getIdentifierValue(), o.getIdentifierScheme());
-        assertTrue(res.isPresent());
-        assertTrue(sg!=res.get());
-        assertEquals(sg, res.get());
-        assertEquals(1, res.get().getUsers().size());
-        assertTrue(res.get().getUsers().contains(u3.get()));
-    }
-
-    @Test
-    @Transactional
-    public void removeOwnerFromServiceGroup() {
-
-        // given
-        DBResource sg = createAndSaveNewServiceGroupWithUsers();
-        Optional<DBUser> u1 = userDao.findUserByUsername(TestConstants.USERNAME_1);
-        Optional<DBUser> u2 = userDao.findUserByCertificateId(TestConstants.USER_CERT_2);
-        Optional<DBResource> osg = testInstance.findServiceGroup(sg.getIdentifierValue(), sg.getIdentifierScheme());
-        DBResource sgDb = osg.get();
-        assertEquals(2, sgDb.getUsers().size());
-        assertTrue(sgDb.getUsers().contains(u1.get()));
-        assertTrue(sgDb.getUsers().contains(u2.get()));
-
-        // when
-        sgDb.getUsers().remove(u2.get());
-        testInstance.update(sgDb);
-        testInstance.clearPersistenceContext();
-
-        // then
-        DBResource res = testInstance.findServiceGroup(sg.getIdentifierValue(), sg.getIdentifierScheme()).get();
-        assertTrue(sgDb!=res);
-        assertEquals(sgDb, res);
-        assertEquals(1, res.getUsers().size());
-        assertTrue(sgDb.getUsers().contains(u1.get()));
-        assertFalse(res.getUsers().contains(u2));
-    }
-
-    @Test
-    @Transactional
-    public void addAndRemoveOwnerFromServiceGroup() {
-        // given
-        DBResource sg = createAndSaveNewServiceGroupWithUsers();
-        Optional<DBUser> u1 = userDao.findUserByUsername(TestConstants.USERNAME_1);
-        Optional<DBUser> u2 = userDao.findUserByCertificateId(TestConstants.USER_CERT_2);
-        Optional<DBUser> u3 = userDao.findUserByUsername(TestConstants.USERNAME_3);
-        Optional<DBResource> osg = testInstance.findServiceGroup(sg.getIdentifierValue(), sg.getIdentifierScheme());
-        DBResource sgDb = osg.get();
-        assertEquals(2, sgDb.getUsers().size());
-        assertTrue(sgDb.getUsers().contains(u1.get()));
-        assertTrue(sgDb.getUsers().contains(u2.get()));
-        assertFalse(sgDb.getUsers().contains(u3.get()));
-        //
-        sgDb.getUsers().add(u3.get());
-        sgDb.getUsers().remove(u2.get());
-        testInstance.update(sgDb);
-        testInstance.clearPersistenceContext();
-        //then
-        DBResource res = testInstance.findServiceGroup(sg.getIdentifierValue(), sg.getIdentifierScheme()).get();
-        assertTrue(sgDb!=res); // different object instances
-        assertEquals(sgDb, res); // same objects
-        assertEquals(2, res.getUsers().size());
-        assertTrue(res.getUsers().contains(u1.get()));
-        assertTrue(res.getUsers().contains(u3.get()));
-        assertFalse(res.getUsers().contains(u2.get()));
-
-    }
-*/
-
-}
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/UserDaoIntegrationTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/UserDaoIntegrationTest.java
index ead58285c..8ca074ee2 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/UserDaoIntegrationTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/UserDaoIntegrationTest.java
@@ -1,12 +1,20 @@
 package eu.europa.ec.edelivery.smp.data.dao;
 
+import eu.europa.ec.edelivery.smp.data.model.user.DBCredential;
 import eu.europa.ec.edelivery.smp.data.model.user.DBUser;
 import eu.europa.ec.edelivery.smp.exceptions.SMPRuntimeException;
+import eu.europa.ec.edelivery.smp.testutil.TestConstants;
+import eu.europa.ec.edelivery.smp.testutil.TestDBUtils;
+import org.hamcrest.CoreMatchers;
+import org.hamcrest.MatcherAssert;
 import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Optional;
 
 import static eu.europa.ec.edelivery.smp.exceptions.ErrorCode.INVALID_USER_NO_IDENTIFIERS;
 import static org.junit.Assert.*;
@@ -18,30 +26,26 @@ import static org.junit.Assert.*;
  * @author Joze Rihtarsic
  * @since 4.1
  */
-@Ignore
 public class UserDaoIntegrationTest extends AbstractBaseDao {
 
     @Autowired
     UserDao testInstance;
 
     @Autowired
-    ResourceDao serviceGroupDao;
+    CredentialDao credentialDao;
 
-    @Rule
-    public ExpectedException expectedEx = ExpectedException.none();
+    @Autowired
+    ResourceDao serviceGroupDao;
 
     @Test
     public void persistUserWithoutIdentifier() {
         // set
         DBUser u = new DBUser();
-        expectedEx.expectMessage(INVALID_USER_NO_IDENTIFIERS.getMessage());
-        expectedEx.expect(SMPRuntimeException.class);
-        // execute
-        testInstance.persistFlushDetach(u);
+        SMPRuntimeException result = assertThrows(SMPRuntimeException.class, () -> testInstance.persistFlushDetach(u));
 
-        fail();
+        MatcherAssert.assertThat(result.getMessage(), CoreMatchers.containsString(INVALID_USER_NO_IDENTIFIERS.getMessage()));
     }
-/*
+
     @Test
     public void persistUserWithUsername() {
         // set
@@ -55,19 +59,14 @@ public class UserDaoIntegrationTest extends AbstractBaseDao {
         assertNotSame(u, ou.get());
         assertEquals(u, ou.get());
         assertEquals(u.getEmailAddress(), ou.get().getEmailAddress());
-        assertEquals(u.getPassword(), ou.get().getPassword());
-        assertEquals(u.getRole(), ou.get().getRole());
         assertEquals(u.getUsername(), ou.get().getUsername());
     }
 
-
     @Test
-    public void persistUserWithUsernameAndEmptyCertificateID() {
-        // if certificate id is null then do not store certificate object to database
-        // because of unique constraint  and null value in mysql is also subject to the constraint!
-        DBUser u = TestDBUtils.createDBUser(TestConstants.USERNAME_1, null);
-        assertNotNull(u.getCertificate());
-        assertNull(u.getCertificate().getCertificateId());
+    public void persistUserWithoutCredentials() {
+
+        DBUser u = TestDBUtils.createDBUserByUsername(TestConstants.USERNAME_1);
+        assertTrue(u.getUserCredentials().isEmpty());
 
         // execute
         testInstance.persistFlushDetach(u);
@@ -77,13 +76,40 @@ public class UserDaoIntegrationTest extends AbstractBaseDao {
         assertNotSame(u, ou.get());
         assertEquals(u, ou.get());
         assertEquals(u.getUsername(), ou.get().getUsername());
-        assertNull(u.getCertificate());
+        assertTrue(u.getUserCredentials().isEmpty());
+    }
+
+    @Test
+    @Transactional
+    public void persistUserWithUsernamePasswordCredential() {
+        // set
+        DBUser u = TestDBUtils.createDBUserByUsername(TestConstants.USERNAME_2);
+        DBCredential credential = TestDBUtils.createDBCredential(TestConstants.USERNAME_2);
+
+        // execute
+        testInstance.persistFlushDetach(u);
+        credential.setUser(u);
+        credentialDao.persistFlushDetach(credential);
+
+        //test
+        Optional<DBUser> ou = testInstance.findUserByUsername(TestConstants.USERNAME_2);
+        assertNotSame(u, ou.get());
+        assertEquals(u, ou.get());
+        assertEquals(u.getEmailAddress(), ou.get().getEmailAddress());
+        assertEquals(1, ou.get().getUserCredentials().size());
+        assertEquals(credential.getValue(), ou.get().getUserCredentials().get(0).getValue());
+        assertEquals(credential.getName(), ou.get().getUserCredentials().get(0).getName());
+        assertEquals(credential.getCredentialTarget(), ou.get().getUserCredentials().get(0).getCredentialTarget());
+        assertEquals(credential.getCredentialType(), ou.get().getUserCredentials().get(0).getCredentialType());
+
     }
 
     @Test
+    @Transactional
     public void persistUserWithCertificate() {
         // set
         DBUser u = TestDBUtils.createDBUserByCertificate(TestConstants.USER_CERT_1);
+        DBCredential credential = u.getUserCredentials().get(0);
 
         // execute
         testInstance.persistFlushDetach(u);
@@ -93,12 +119,18 @@ public class UserDaoIntegrationTest extends AbstractBaseDao {
         assertNotSame(u, ou.get());
         assertEquals(u, ou.get());
         assertEquals(u.getEmailAddress(), ou.get().getEmailAddress());
-        assertEquals(u.getCertificate().getCertificateId(), ou.get().getCertificate().getCertificateId());
-        assertEquals(u.getCertificate().getValidFrom().toInstant(),
-                ou.get().getCertificate().getValidFrom().toInstant());
-
-        assertEquals(u.getCertificate().getValidTo().toInstant(),
-                ou.get().getCertificate().getValidTo().toInstant());
+        assertEquals(1, ou.get().getUserCredentials().size());
+        assertEquals(credential.getValue(), ou.get().getUserCredentials().get(0).getValue());
+        assertEquals(credential.getName(), ou.get().getUserCredentials().get(0).getName());
+        assertEquals(credential.getCredentialTarget(), ou.get().getUserCredentials().get(0).getCredentialTarget());
+        assertEquals(credential.getCredentialType(), ou.get().getUserCredentials().get(0).getCredentialType());
+
+        assertEquals(credential.getCertificate().getCertificateId(), ou.get().getUserCredentials().get(0).getCertificate().getCertificateId());
+        assertEquals(credential.getCertificate().getValidFrom().toInstant(),
+                ou.get().getUserCredentials().get(0).getCertificate().getValidFrom().toInstant());
+
+        assertEquals(credential.getCertificate().getValidTo().toInstant(),
+                ou.get().getUserCredentials().get(0).getCertificate().getValidTo().toInstant());
     }
 
     @Test
@@ -114,20 +146,16 @@ public class UserDaoIntegrationTest extends AbstractBaseDao {
         assertNotSame(u, ou.get());
         assertEquals(u, ou.get());
         assertEquals(u.getEmailAddress(), ou.get().getEmailAddress());
-        assertEquals(u.getCertificate().getCertificateId(), ou.get().getCertificate().getCertificateId());
-
-        System.out.println("Zone: " + u.getCertificate().getValidFrom().toInstant());
-        assertEquals(u.getCertificate().getValidFrom().toInstant(),
-                ou.get().getCertificate().getValidFrom().toInstant());
-        assertEquals(u.getCertificate().getValidTo().toInstant(),
-                ou.get().getCertificate().getValidTo().toInstant());
     }
 
     @Test
+    @Transactional
     public void findUsernameUserByIdentifier() {
         // set
         DBUser u = TestDBUtils.createDBUserByUsername(TestConstants.USERNAME_1);
-
+        DBCredential credential = TestDBUtils.createDBCredentialForUserAccessToken(u, null, null, null);
+        credential.setName(TestConstants.USERNAME_TOKEN_1);
+        u.getUserCredentials().add(credential);
         // execute
         testInstance.persistFlushDetach(u);
 
@@ -140,15 +168,17 @@ public class UserDaoIntegrationTest extends AbstractBaseDao {
 
     @Test
     public void deleteUserWithCertificate() {
-        // givem
-        DBUser u = TestDBUtils.createDBUserByCertificate(UUID.randomUUID().toString());
+        // given
+        DBUser u = TestDBUtils.createDBUserByCertificate(TestConstants.USER_CERT_1);
+        DBCredential credential = u.getUserCredentials().get(0);
+
         testInstance.persistFlushDetach(u);
-        assertNotNull(u.getId());
+        assertNotNull(credential.getName());
 
         // when then
         testInstance.removeById(u.getId());
         //test
-        Optional<DBUser> ou = testInstance.findUserByIdentifier(u.getCertificate().getCertificateId());
+        Optional<DBUser> ou = testInstance.findUserByIdentifier(credential.getName());
         assertFalse(ou.isPresent());
 
     }
@@ -200,35 +230,4 @@ public class UserDaoIntegrationTest extends AbstractBaseDao {
         assertEquals(u.getEmailAddress(), ou.get().getEmailAddress());
 
     }
-
-    @Test
-    public void testValidateUsersForDeleteOKScenario() {
-        // set
-        DBUser u = TestDBUtils.createDBUserByUsername(TestConstants.USERNAME_1.toLowerCase());
-        testInstance.persistFlushDetach(u);
-
-        // execute
-        List<DBUserDeleteValidation> lst = testInstance.validateUsersForDelete(Collections.singletonList(u.getId()));
-        assertTrue(lst.isEmpty());
-    }
-
-    @Test
-    public void testValidateUsersForDeleteUserIsOwner() {
-        // set
-        DBUser u = TestDBUtils.createDBUserByUsername(TestConstants.USERNAME_1.toLowerCase());
-        DBResource sg = TestDBUtils.createDBServiceGroup();
-        testInstance.persistFlushDetach(u);
-        //sg.addUser(u);
-
-        serviceGroupDao.persistFlushDetach(sg);
-
-
-        // execute
-        List<DBUserDeleteValidation> lst = testInstance.validateUsersForDelete(Collections.singletonList(u.getId()));
-        assertEquals(1, lst.size());
-        assertEquals(u.getUsername(), lst.get(0).getUsername());
-        assertEquals(1, lst.get(0).getCount().intValue());
-    }
-
- */
 }
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/AbstractServiceIntegrationTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/AbstractServiceIntegrationTest.java
index 2749a5f55..ad0fe1c6e 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/AbstractServiceIntegrationTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/AbstractServiceIntegrationTest.java
@@ -42,7 +42,7 @@ import static eu.europa.ec.edelivery.smp.testutil.TestConstants.*;
 
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration(classes = {IdentifierService.class,SmlConnector.class, SmpXmlSignatureService.class, MailService.class,
-        DomainService.class, ServiceMetadataService.class,
+        DomainService.class,
         ResourceDao.class, SubresourceDao.class, DomainDao.class, UserDao.class,DBAssertion.class, ConfigurationDao.class, AlertDao.class,
         UITruststoreService.class, UIKeystoreService.class, ConversionTestConfig.class, SMLIntegrationService.class,
         CRLVerifierService.class,
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/sml/SmlClientFactoryAuthenticationByClientCertFromKeystoreTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/sml/SmlClientFactoryAuthenticationByClientCertFromKeystoreTest.java
index 20b9efdc9..dacb35233 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/sml/SmlClientFactoryAuthenticationByClientCertFromKeystoreTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/sml/SmlClientFactoryAuthenticationByClientCertFromKeystoreTest.java
@@ -16,7 +16,7 @@ package eu.europa.ec.edelivery.smp.sml;
 import eu.europa.ec.bdmsl.ws.soap.IManageParticipantIdentifierWS;
 import eu.europa.ec.bdmsl.ws.soap.IManageServiceMetadataWS;
 import eu.europa.ec.edelivery.smp.data.model.DBDomain;
-import eu.europa.ec.edelivery.smp.services.AbstractServiceIntegrationTest;
+import eu.europa.ec.edelivery.smp.services.AbstractServiceTest;
 import eu.europa.ec.edelivery.smp.services.ConfigurationService;
 import eu.europa.ec.edelivery.smp.services.ui.UIKeystoreService;
 import org.apache.cxf.configuration.jsse.TLSClientParameters;
@@ -24,16 +24,12 @@ import org.apache.cxf.endpoint.Client;
 import org.apache.cxf.frontend.ClientProxy;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.transport.http.HTTPConduit;
+import org.hamcrest.CoreMatchers;
+import org.hamcrest.MatcherAssert;
 import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Rule;
 import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.junit.runner.RunWith;
 import org.mockito.Mockito;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringRunner;
 import org.springframework.test.util.ReflectionTestUtils;
 
 import javax.net.ssl.KeyManager;
@@ -52,14 +48,10 @@ import static org.junit.Assert.*;
 /**
  * Created by gutowpa on 08/01/2018.
  */
-@Ignore
-@RunWith(SpringRunner.class)
-@ContextConfiguration(classes = {SmlClientFactory.class, SmlConnector.class})
-public class SmlClientFactoryAuthenticationByClientCertFromKeystoreTest extends AbstractServiceIntegrationTest {
+public class SmlClientFactoryAuthenticationByClientCertFromKeystoreTest extends AbstractServiceTest {
 
-
-    @Rule
-    public ExpectedException expectedEx = ExpectedException.none();
+    private static final String CERTIFICATE_DN_SECOND_DOMAIN = "CN=Second Domain,OU=edelivery,O=digit,C=eu";
+    private static final String CERTIFICATE_DN_FIRST_DOMAIN = "CN=SMP Mock Services,OU=DIGIT,O=European Commision,C=BE";
 
     Path resourceDirectory = Paths.get("src", "test", "resources", "keystores");
 
@@ -112,7 +104,7 @@ public class SmlClientFactoryAuthenticationByClientCertFromKeystoreTest extends
         Map httpHeaders = (Map) requestContext.get(Message.PROTOCOL_HEADERS);
         assertTrue(httpHeaders == null || httpHeaders.isEmpty());
 
-        assertEquals("C=BE,O=CEF Digital,OU=SMP,CN=Secodn domain", clientCert.getSubjectDN().getName());
+        assertEquals(CERTIFICATE_DN_SECOND_DOMAIN, clientCert.getSubjectX500Principal().getName());
         assertEquals("https://localhost/edelivery-sml/manageparticipantidentifier", requestContext.get(Message.ENDPOINT_ADDRESS));
     }
 
@@ -137,7 +129,7 @@ public class SmlClientFactoryAuthenticationByClientCertFromKeystoreTest extends
         Map httpHeaders = (Map) requestContext.get(Message.PROTOCOL_HEADERS);
         assertTrue(httpHeaders == null || httpHeaders.isEmpty());
 
-        assertEquals("C=BE,O=CEF Digital,OU=SMP,CN=Secodn domain", clientCert.getSubjectDN().getName());
+        assertEquals(CERTIFICATE_DN_SECOND_DOMAIN, clientCert.getSubjectX500Principal().getName());
         assertEquals("https://localhost/edelivery-sml/manageservicemetadata", requestContext.get(Message.ENDPOINT_ADDRESS));
     }
 
@@ -157,7 +149,7 @@ public class SmlClientFactoryAuthenticationByClientCertFromKeystoreTest extends
         Map<String, Object> requestContext = cxfClient.getRequestContext();
         X509Certificate clientCert = getClientCertFromKeystore(cxfClient);
 
-        assertEquals("C=BE,O=European Commision,OU=DIGIT,CN=SMP Mock Services", clientCert.getSubjectDN().getName());
+        assertEquals(CERTIFICATE_DN_FIRST_DOMAIN, clientCert.getSubjectX500Principal().getName());
         assertEquals("https://localhost/edelivery-sml/changedEndpoint", requestContext.get(Message.ENDPOINT_ADDRESS));
     }
 
@@ -178,7 +170,7 @@ public class SmlClientFactoryAuthenticationByClientCertFromKeystoreTest extends
         Map<String, Object> requestContext = cxfClient.getRequestContext();
         X509Certificate clientCert = getClientCertFromKeystore(cxfClient);
 
-        assertEquals("C=BE,O=European Commision,OU=DIGIT,CN=SMP Mock Services", clientCert.getSubjectDN().getName());
+        assertEquals(CERTIFICATE_DN_FIRST_DOMAIN, clientCert.getSubjectX500Principal().getName());
         assertEquals("https://localhost/edelivery-sml/changedEndpoint", requestContext.get(Message.ENDPOINT_ADDRESS));
     }
 
@@ -190,13 +182,10 @@ public class SmlClientFactoryAuthenticationByClientCertFromKeystoreTest extends
         domain.setSmlClientKeyAlias(null);
         domain.setSmlClientCertAuth(false);
 
-        expectedEx.expect(IllegalStateException.class);
-        expectedEx.expectMessage("More than one key in Keystore! Define alias for the domain SML authentication!");
-
-
-        // when
-        testInstance.configureClient("changedEndpoint", client, domain);
+        IllegalStateException result = assertThrows(IllegalStateException.class,
+                () -> testInstance.configureClient("changedEndpoint", client, domain));
 
+        MatcherAssert.assertThat(result.getMessage(), CoreMatchers.containsString("Invalid integration configuration. Missing Client cert configuration!"));
     }
 
     @Test
@@ -208,10 +197,10 @@ public class SmlClientFactoryAuthenticationByClientCertFromKeystoreTest extends
         domain.setSmlClientKeyAlias(null);
         domain.setSmlClientCertAuth(false);
 
-        expectedEx.expect(IllegalStateException.class);
-        expectedEx.expectMessage("More than one key in Keystore! Define alias for the domain SML authentication!");
-        // when
-        testInstance.configureClient("changedEndpoint", client, domain);
+        IllegalStateException result = assertThrows(IllegalStateException.class,
+                () -> testInstance.configureClient("changedEndpoint", client, domain));
+
+        MatcherAssert.assertThat(result.getMessage(), CoreMatchers.containsString("Invalid integration configuration. Missing Client cert configuration!"));
     }
 
     @Test
@@ -238,7 +227,7 @@ public class SmlClientFactoryAuthenticationByClientCertFromKeystoreTest extends
         Map<String, Object> requestContext = cxfClient.getRequestContext();
         X509Certificate clientCert = getClientCertFromKeystore(cxfClient);
 
-        assertEquals("C=BE,O=European Commision,OU=DIGIT,CN=SMP Mock Services", clientCert.getSubjectDN().getName());
+        assertEquals(CERTIFICATE_DN_FIRST_DOMAIN, clientCert.getSubjectX500Principal().getName());
 
     }
 
@@ -253,5 +242,4 @@ public class SmlClientFactoryAuthenticationByClientCertFromKeystoreTest extends
         assertNotNull(key);
         return ((X509KeyManager) keyManager).getCertificateChain(alias)[0];
     }
-
 }
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/sml/SmlConnectorDomainTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/sml/SmlConnectorDomainTest.java
index 8be50f23e..c0cb4d495 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/sml/SmlConnectorDomainTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/sml/SmlConnectorDomainTest.java
@@ -22,6 +22,7 @@ import eu.europa.ec.edelivery.smp.config.SmlIntegrationConfiguration;
 import eu.europa.ec.edelivery.smp.data.model.DBDomain;
 import eu.europa.ec.edelivery.smp.exceptions.SMPRuntimeException;
 import eu.europa.ec.edelivery.smp.services.AbstractServiceIntegrationTest;
+import eu.europa.ec.edelivery.smp.services.AbstractServiceTest;
 import eu.europa.ec.edelivery.smp.services.ConfigurationService;
 import org.junit.Before;
 import org.junit.Ignore;
@@ -47,10 +48,7 @@ import static org.mockito.Mockito.verify;
  * Created by JRC
  * since 4.1.
  */
-@Ignore
-@RunWith(SpringRunner.class)
-@ContextConfiguration(classes = {SmlConnector.class, SmlIntegrationConfiguration.class})
-public class SmlConnectorDomainTest extends AbstractServiceIntegrationTest {
+public class SmlConnectorDomainTest extends AbstractServiceTest {
 
     @Autowired
     protected ConfigurationService configurationService;
@@ -222,5 +220,4 @@ public class SmlConnectorDomainTest extends AbstractServiceIntegrationTest {
 
         assertEquals("single_domain_key", alias);
     }
-
 }
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestDBUtils.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestDBUtils.java
index 83b2b0090..48317b202 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestDBUtils.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestDBUtils.java
@@ -187,8 +187,8 @@ public class TestDBUtils {
     }
 
 
-    public static DBCredential createDBCredential() {
-        return createDBCredential("name", "value", CredentialType.USERNAME_PASSWORD, CredentialTargetType.UI);
+    public static DBCredential createDBCredential(String name) {
+        return createDBCredential(name, "value", CredentialType.USERNAME_PASSWORD, CredentialTargetType.UI);
     }
 
     public static DBCredential createDBCredentialForUser(DBUser user, OffsetDateTime from , OffsetDateTime to, OffsetDateTime lastAlertSent ) {
@@ -294,7 +294,11 @@ public class TestDBUtils {
 
     public static DBUser createDBUser(String userName, String certId, OffsetDateTime validFrom, OffsetDateTime validTo) {
         DBUser dbuser = createDBUserByUsername(userName);
-        // dbuser.setCertificate(createDBCertificate(certId, validFrom, validTo));
+        DBCredential credential = createDBCredential(dbuser, certId,"", CredentialType.CERTIFICATE, CredentialTargetType.REST_API);
+        credential.setActiveFrom(validFrom);
+        credential.setExpireOn(validTo);
+        credential.setCertificate(createDBCertificate(certId, validFrom, validTo));
+        dbuser.getUserCredentials().add(credential);
         return dbuser;
     }
     
diff --git a/smp-server-library/src/test/resources/keystores/smp-keystore_multiple_domains.jks b/smp-server-library/src/test/resources/keystores/smp-keystore_multiple_domains.jks
index 3e7e6dfa8fd3fea870ab705725102380da639860..8d2c37f344462849a9f277661479eeb6544b8a53 100644
GIT binary patch
delta 3398
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

delta 1328
zcmV-01<(4!EBhJ@{_Xzl0000200002kqjJvXG-%Aa{vGZ0x*IE{xA*(3M&Qy1OX}n
z5di@O00e>r>gEkd{bRabZZOH3FQip0@w@5qp8H2&?%NIdo!X_K!lC~pg~t&nNkgDf
zJRY5Hm5b`{%+m|T!rOr|{X&GWk+pDLO3}Kw{8?{LQ=vL<G<X<e26Kw#Ll=Y<;bG)|
zryW^J-{@+O_(gY9M~_*I*}qeQ@J+<54>HiZLRVdtoN^XGm!5yox=S!Bu>f4oa&RBu
zF)YLst#QOrM0lnoA@bk;B`_-T{x#|~1>4gDYbV{luC#w0y}_i(xI;HM!a^Y*eN@&F
z)PEdA1ssM9@hmaA3}^i#0*L~4QzeIgJyFAJfT&~bP5A_F<K|UZ4@HlwkF?u*#pd$Q
zYruCcd&dH*3f>YjNxrJI^V}>>xeGLbeP83%J*THa_%G-J9b5PT?UxD!)`7zdv_y>7
zY3x7gSlBUY52))A0v8MhwtYP~kLUJ%bS@F$WpHgziqzj1T4MQ5dMdU!Z#}(#gnoEV
zrZ5P=%H(x->L)mgC-tIGgKS(xACvWaB$U7`qfl>7c3yX#fYM7>Ds`<OcWfdQ^>8<<
z%W5NCk*d6nxOHIEvzz9x7{e)nW>8?~4WF60>RB`@c)Afj2;G?@RCPNHp@kFLhhS>9
zf69zHs$Dqw-Ww*L-gF8<7jNEwrPSNl^7My*02Ye_-eF4D9Bc-VPiKtkiO<u3?yB>T
zwRAN3ar0CR6QKLJohY#SH16n58p0VgUCJ+)5rXaxt!zCH8(B1dE?&C0MH2*=v_-v=
zicD)oN~G=O5=d^O=PRx>t4~5;8XWDuDu29kMoFw_&<}tC-R&g0H<*8aEcyT34QU49
zICgs{bL1MS9$#J3h_6GFjS@;4#s%s&O*Gmx#k&D;GKF%fj)E6wBRB~!tS5vuJ1R&c
znW)D<KHz}Rc7qP?=629|t^98Yl@m-3$@4#vIxKWL)|6$ri$IVw#cp#JjUhD@Mqvv3
zqNSoSi?hSdf_w#x3LSiZ;A%F1_v}_IywRb0kbs_iqC~4KvXu+vr#;A5gH=2u$|l$O
zfD5}pb`Kzulk_d$`(^$p9|a{EOA+j2`CjR>avx=h*tyC#h^qgJ!G<@Zf^LsD?>>Ut
z9?oTkJblm5by?e52^^d(qGB6LOCEuCzD9mAq1U3v>-}(58DLp|?yMpu-ufX4#E{!8
z&w!}>Q7FpTDMb%@EwTr%q@@-So~MxsXYA(sqh}1SY?Ughnb$B3D-J&|Mc+FaTlLRT
z9Zf;#>C>Sqkm=MTateJInLcZ~Ky`ZbuA%L%5heQ&=GGs^<r63|hh`G6k+RB9c+{^q
z;Uau;gO43Gj}l*hDbRLMD;(Ld>{Z=GHhfOJG*s*lUuj->6G)3QQW5iMn2N=;#*(38
z0odCiJebkeQFEvAEuDdbx1i(vi>U3Osp;U7W2aAuwGsBz{xVIg`{r0~lCzRpUu5b`
z&m-N&U@Mi*Y<@9lVGWNKR4z4+`hPfGpbqfD|1TJm2*YH5Zrtx}`%4a_RZQqC`E)r9
znnuZPT++y2xa2yQ_ArI<m59rF+#`d>YbRgR8N9$te$i|C^)##ZZY_Bi(8@B^bAsZB
zy0o@vcs)arO`4H;I|?H~MeJ$Z5xw_D*gxo!QK=B{&)4{VbN}f}x!^A|FcJ}e9EMrU
mr`g+_7gbsT`LkyYNC*^hW|<JTSU4oFle-?i99Db4?+<?|O?d<W

-- 
GitLab