diff --git a/.gitignore b/.gitignore index be91110e8..56bbf5c96 100644 --- a/.gitignore +++ b/.gitignore @@ -11,5 +11,8 @@ # Maven target +# Test +test-output + # Visual Studio Code project files *.factorypath \ No newline at end of file diff --git a/README.md b/README.md index 3ef3dac21..5ed547517 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ +# Moved to [Gluu4 monorepo](https://github.com/GluuFederation/gluu4/tree/main/oxCore) oxCore ====== diff --git a/checkstyle.xml b/checkstyle.xml index 6fbf532cc..9281e7228 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -187,4 +187,4 @@ - \ No newline at end of file + diff --git a/core-cache/pom.xml b/core-cache/pom.xml new file mode 100644 index 000000000..68f02ee4d --- /dev/null +++ b/core-cache/pom.xml @@ -0,0 +1,115 @@ + + + 4.0.0 + org.gluu + oxcore-cache + Caches support + + + org.gluu + oxcore + 4.5.6-SNAPSHOT + + + + ${maven.min-version} + + + + + + src/main/resources + true + + **/*.xml + **/services/* + **/*.properties + + + + + + src/test/resources + true + + **/*.xml + **/services/* + **/*.properties + + + + + + + + + ${project.groupId} + gluu-orm-core + + + ${project.groupId} + oxcore-util + + + + + javax.enterprise + cdi-api + provided + + + + javax.inject + javax.inject + + + + + net.spy + spymemcached + + + redis.clients + jedis + + + net.jodah + expiringmap + + + commons-io + commons-io + + + org.apache.httpcomponents + httpcore + + + org.apache.httpcomponents + httpclient + + + + jakarta.xml.bind + jakarta.xml.bind-api + + + javax.annotation + javax.annotation-api + + + + + org.testng + testng + + + + javax.annotation + javax.annotation-api + + + + \ No newline at end of file diff --git a/oxService/src/main/java/org/gluu/service/CacheService.java b/core-cache/src/main/java/org/gluu/service/BaseCacheService.java similarity index 57% rename from oxService/src/main/java/org/gluu/service/CacheService.java rename to core-cache/src/main/java/org/gluu/service/BaseCacheService.java index b831f55b7..b3ed5ae52 100644 --- a/oxService/src/main/java/org/gluu/service/CacheService.java +++ b/core-cache/src/main/java/org/gluu/service/BaseCacheService.java @@ -10,9 +10,7 @@ import org.gluu.service.cache.CacheProviderType; import org.slf4j.Logger; -import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; -import javax.inject.Named; import java.util.Date; import java.util.function.Supplier; @@ -22,24 +20,25 @@ * @author Yuriy Movchan Date: 01.24.2012 * @author Yuriy Zabrovarnyy Date: 02.02.2017 */ -@ApplicationScoped -@Named -public class CacheService implements CacheInterface { +public abstract class BaseCacheService implements CacheInterface { - private static int DEFAULT_EXPIRATION = 60; + public static int DEFAULT_EXPIRATION = 60; - @Inject - private CacheProvider cacheProvider; - - @Inject + @Inject private Logger log; public Object get(String key) { + CacheProvider cacheProvider = getCacheProvider(); if (cacheProvider == null) { + log.error("Cache provider is invalid!"); return null; } - return cacheProvider.get(key); + log.trace("Request data, key '{}'", key); + Object value = cacheProvider.get(key); + log.trace("Loaded data, key '{}': '{}'", key, value); + + return value; } public T getWithPut(String key, Supplier loadFunction, int expirationInSeconds) { @@ -47,56 +46,80 @@ public T getWithPut(String key, Supplier loadFunction, int expirationInSe return (T) get(key); } - if (CacheProviderType.NATIVE_PERSISTENCE == cacheProvider.getProviderType()) { + CacheProvider cacheProvider = getCacheProvider(); + + if (CacheProviderType.NATIVE_PERSISTENCE == cacheProvider.getProviderType()) { + log.trace("Loading data from DB without cache, key '{}'", key); return loadFunction.get(); } final Object value = get(key); if (value != null) { - log.trace("Loaded from cache, key: " + key); + log.trace("Loaded from cache, key: '{}'", key); return (T) value; } else { + log.trace("Key not in cache. Searching value via load function, key: '{}'", key); final T loaded = loadFunction.get(); if (loaded == null) { + log.trace("Key not in cache. There is no value, key: '{}'", key); return null; } try { put(expirationInSeconds, key, loaded); } catch (Exception e) { - log.error("Failed to put object into cache, key: " + key, e); // we don't want prevent returning loaded value due to failure with put + log.error("Failed to put object into cache, key: '{}'", key, e); // we don't want prevent returning loaded value due to failure with put } return loaded; } } public void put(int expirationInSeconds, String key, Object object) { - if (cacheProvider != null) { - cacheProvider.put(expirationInSeconds, key, object); + CacheProvider cacheProvider = getCacheProvider(); + if (cacheProvider == null) { + log.error("Cache provider is invalid!"); + return; } + + log.trace("Put data, key '{}': '{}'", key, object); + cacheProvider.put(expirationInSeconds, key, object); } public void remove(String key) { - if (cacheProvider == null) { + CacheProvider cacheProvider = getCacheProvider(); + if (cacheProvider == null) { + log.error("Cache provider is invalid!"); return; } + log.trace("Remove data, key '{}'", key); cacheProvider.remove(key); } public void clear() { - if (cacheProvider != null) { - cacheProvider.clear(); + CacheProvider cacheProvider = getCacheProvider(); + if (cacheProvider == null) { + log.error("Cache provider is invalid!"); + return; } + + log.trace("Clear cache"); + cacheProvider.clear(); } @Override public void cleanup(Date now) { - if (cacheProvider != null) { - cacheProvider.cleanup(now); - } + CacheProvider cacheProvider = getCacheProvider(); + if (cacheProvider == null) { + log.error("Cache provider is invalid!"); + return; + } + + log.trace("Clean up cache"); + cacheProvider.cleanup(now); } + @Deprecated public void put(String key, Object object) { put(DEFAULT_EXPIRATION, key, object); } @@ -122,4 +145,7 @@ public void put(String expirationInSeconds, String key, Object object) { public void remove(String region, String key) { remove(key); } + + protected abstract CacheProvider getCacheProvider(); + } diff --git a/core-cache/src/main/java/org/gluu/service/CacheService.java b/core-cache/src/main/java/org/gluu/service/CacheService.java new file mode 100644 index 000000000..8a7826009 --- /dev/null +++ b/core-cache/src/main/java/org/gluu/service/CacheService.java @@ -0,0 +1,32 @@ +/* + * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2014, Gluu + */ +package org.gluu.service; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; +import javax.inject.Named; + +import org.gluu.service.cache.CacheProvider; + +/** + * Provides operations with cache + * + * @author Yuriy Movchan Date: 01.24.2012 + * @author Yuriy Zabrovarnyy Date: 02.02.2017 + */ +@ApplicationScoped +@Named +public class CacheService extends BaseCacheService { + + @Inject + private CacheProvider cacheProvider; + + @Override + protected CacheProvider getCacheProvider() { + return cacheProvider; + } + +} diff --git a/oxService/src/main/java/org/gluu/service/cache/AbstractCacheProvider.java b/core-cache/src/main/java/org/gluu/service/cache/AbstractCacheProvider.java similarity index 100% rename from oxService/src/main/java/org/gluu/service/cache/AbstractCacheProvider.java rename to core-cache/src/main/java/org/gluu/service/cache/AbstractCacheProvider.java diff --git a/oxService/src/main/java/org/gluu/service/cache/AbstractRedisProvider.java b/core-cache/src/main/java/org/gluu/service/cache/AbstractRedisProvider.java similarity index 59% rename from oxService/src/main/java/org/gluu/service/cache/AbstractRedisProvider.java rename to core-cache/src/main/java/org/gluu/service/cache/AbstractRedisProvider.java index 1de9004a5..3284b6d7b 100644 --- a/oxService/src/main/java/org/gluu/service/cache/AbstractRedisProvider.java +++ b/core-cache/src/main/java/org/gluu/service/cache/AbstractRedisProvider.java @@ -1,20 +1,28 @@ package org.gluu.service.cache; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import redis.clients.jedis.HostAndPort; +import redis.clients.jedis.JedisPoolConfig; /** * @author yuriyz */ public abstract class AbstractRedisProvider { - private final static Logger LOG = LoggerFactory.getLogger(AbstractRedisProvider.class); protected RedisConfiguration redisConfiguration; public AbstractRedisProvider(RedisConfiguration redisConfiguration) { this.redisConfiguration = redisConfiguration; + HostAndPort.setLocalhost("127.0.0.1"); } + public JedisPoolConfig createPoolConfig() { + JedisPoolConfig poolConfig = new JedisPoolConfig(); + poolConfig.setMaxTotal(redisConfiguration.getMaxTotalConnections()); + poolConfig.setMaxIdle(redisConfiguration.getMaxIdleConnections()); + poolConfig.setMinIdle(2); + return poolConfig; + } + public RedisConfiguration getRedisConfiguration() { return redisConfiguration; } @@ -26,11 +34,21 @@ public void testConnection() { } } + public boolean isConnected() { + put(2, "testKey", "testValue"); + if (!"testValue".equals(get("testKey"))) { + return false; + } + return true; + } + public abstract void create(); public abstract void destroy(); public abstract Object getDelegate(); + + public abstract boolean hasKey(String key); public abstract Object get(String key); diff --git a/oxService/src/main/java/org/gluu/service/cache/CacheConfiguration.java b/core-cache/src/main/java/org/gluu/service/cache/CacheConfiguration.java similarity index 99% rename from oxService/src/main/java/org/gluu/service/cache/CacheConfiguration.java rename to core-cache/src/main/java/org/gluu/service/cache/CacheConfiguration.java index 1513e8e07..ca77e4164 100644 --- a/oxService/src/main/java/org/gluu/service/cache/CacheConfiguration.java +++ b/core-cache/src/main/java/org/gluu/service/cache/CacheConfiguration.java @@ -1,9 +1,10 @@ package org.gluu.service.cache; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import java.io.Serializable; import javax.enterprise.inject.Vetoed; -import java.io.Serializable; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; /** diff --git a/oxService/src/main/java/org/gluu/service/cache/CacheInterface.java b/core-cache/src/main/java/org/gluu/service/cache/CacheInterface.java similarity index 100% rename from oxService/src/main/java/org/gluu/service/cache/CacheInterface.java rename to core-cache/src/main/java/org/gluu/service/cache/CacheInterface.java diff --git a/oxService/src/main/java/org/gluu/service/cache/CacheProvider.java b/core-cache/src/main/java/org/gluu/service/cache/CacheProvider.java similarity index 90% rename from oxService/src/main/java/org/gluu/service/cache/CacheProvider.java rename to core-cache/src/main/java/org/gluu/service/cache/CacheProvider.java index 461d0686d..a5769769b 100644 --- a/oxService/src/main/java/org/gluu/service/cache/CacheProvider.java +++ b/core-cache/src/main/java/org/gluu/service/cache/CacheProvider.java @@ -9,6 +9,11 @@ public abstract class CacheProvider implements CacheInterface { */ public abstract T getDelegate(); + /* + * Method to check if there is key in cache + */ + public abstract boolean hasKey(String key); + /** * Fetches an object for the given key from the cache and returns it if found. * Only the specified cache region will be searched. diff --git a/oxService/src/main/java/org/gluu/service/cache/CacheProviderFactory.java b/core-cache/src/main/java/org/gluu/service/cache/CacheProviderFactory.java similarity index 69% rename from oxService/src/main/java/org/gluu/service/cache/CacheProviderFactory.java rename to core-cache/src/main/java/org/gluu/service/cache/CacheProviderFactory.java index 61c110600..cc4452604 100644 --- a/oxService/src/main/java/org/gluu/service/cache/CacheProviderFactory.java +++ b/core-cache/src/main/java/org/gluu/service/cache/CacheProviderFactory.java @@ -1,7 +1,5 @@ package org.gluu.service.cache; -import org.slf4j.Logger; - import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Any; import javax.enterprise.inject.Instance; @@ -9,6 +7,8 @@ import javax.inject.Inject; import javax.inject.Named; +import org.slf4j.Logger; + /** * @author yuriyz on 02/21/2017. */ @@ -31,9 +31,12 @@ public class CacheProviderFactory { public CacheProvider getCacheProvider() { log.debug("Started to create cache provider"); - AbstractCacheProvider cacheProvider = null; - CacheProviderType cacheProviderType = cacheConfiguration.getCacheProviderType(); + return getCacheProvider(cacheConfiguration); + } + + public CacheProvider getCacheProvider(CacheConfiguration cacheConfiguration) { + CacheProviderType cacheProviderType = cacheConfiguration.getCacheProviderType(); if (cacheProviderType == null) { log.error("Failed to initialize cacheProvider, cacheProviderType is null. Fallback to IN_MEMORY type."); @@ -41,6 +44,7 @@ public CacheProvider getCacheProvider() { } // Create proxied bean + AbstractCacheProvider cacheProvider = null; switch (cacheProviderType) { case IN_MEMORY: cacheProvider = instance.select(InMemoryCacheProvider.class).get(); @@ -62,6 +66,24 @@ public CacheProvider getCacheProvider() { cacheProvider.create(); + return cacheProvider; + } + + @Produces + @ApplicationScoped + @LocalCache + public CacheProvider getLocalCacheProvider() { + log.debug("Started to create local cache provider"); + + CacheProviderType cacheProviderType = CacheProviderType.IN_MEMORY; + AbstractCacheProvider cacheProvider = instance.select(InMemoryCacheProvider.class).get(); + + if (cacheProvider == null) { + throw new RuntimeException("Failed to initialize cacheProvider, cacheProviderType is unsupported: " + cacheProviderType); + } + + cacheProvider.create(); + return cacheProvider; } diff --git a/oxService/src/main/java/org/gluu/service/cache/CacheProviderType.java b/core-cache/src/main/java/org/gluu/service/cache/CacheProviderType.java similarity index 100% rename from oxService/src/main/java/org/gluu/service/cache/CacheProviderType.java rename to core-cache/src/main/java/org/gluu/service/cache/CacheProviderType.java diff --git a/oxService/src/main/java/org/gluu/service/cache/InMemoryCacheProvider.java b/core-cache/src/main/java/org/gluu/service/cache/InMemoryCacheProvider.java similarity index 82% rename from oxService/src/main/java/org/gluu/service/cache/InMemoryCacheProvider.java rename to core-cache/src/main/java/org/gluu/service/cache/InMemoryCacheProvider.java index f742a0512..aad2c7bb8 100644 --- a/oxService/src/main/java/org/gluu/service/cache/InMemoryCacheProvider.java +++ b/core-cache/src/main/java/org/gluu/service/cache/InMemoryCacheProvider.java @@ -18,7 +18,8 @@ @ApplicationScoped public class InMemoryCacheProvider extends AbstractCacheProvider { - private static final Logger LOG = LoggerFactory.getLogger(InMemoryCacheProvider.class); + @Inject + private Logger log; @Inject private CacheConfiguration cacheConfiguration; @@ -36,23 +37,28 @@ public void init() { } public void create() { - LOG.debug("Starting InMemoryCacheProvider ..."); + log.debug("Starting InMemoryCacheProvider ..."); try { map = ExpiringMap.builder().expirationPolicy(ExpirationPolicy.CREATED).variableExpiration().build(); - LOG.debug("InMemoryCacheProvider started."); + log.debug("InMemoryCacheProvider started."); } catch (Exception e) { throw new IllegalStateException("Error starting InMemoryCacheProvider", e); } } + public void configure(CacheConfiguration cacheConfiguration) { + this.log = LoggerFactory.getLogger(InMemoryCacheProvider.class); + this.cacheConfiguration = cacheConfiguration; + } + @PreDestroy public void destroy() { - LOG.debug("Destroying InMemoryCacheProvider"); + log.debug("Destroying InMemoryCacheProvider"); map.clear(); - LOG.debug("Destroyed InMemoryCacheProvider"); + log.debug("Destroyed InMemoryCacheProvider"); } @Override @@ -60,6 +66,11 @@ public ExpiringMap getDelegate() { return map; } + @Override + public boolean hasKey(String key) { + return map.containsKey(key); + } + @Override public Object get(String key) { return map.get(key); diff --git a/oxService/src/main/java/org/gluu/service/cache/InMemoryConfiguration.java b/core-cache/src/main/java/org/gluu/service/cache/InMemoryConfiguration.java similarity index 99% rename from oxService/src/main/java/org/gluu/service/cache/InMemoryConfiguration.java rename to core-cache/src/main/java/org/gluu/service/cache/InMemoryConfiguration.java index 13b499fc3..84ae87567 100644 --- a/oxService/src/main/java/org/gluu/service/cache/InMemoryConfiguration.java +++ b/core-cache/src/main/java/org/gluu/service/cache/InMemoryConfiguration.java @@ -1,9 +1,10 @@ package org.gluu.service.cache; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import java.io.Serializable; import javax.xml.bind.annotation.XmlElement; -import java.io.Serializable; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; /** diff --git a/core-cache/src/main/java/org/gluu/service/cache/LocalCache.java b/core-cache/src/main/java/org/gluu/service/cache/LocalCache.java new file mode 100644 index 000000000..02aa96061 --- /dev/null +++ b/core-cache/src/main/java/org/gluu/service/cache/LocalCache.java @@ -0,0 +1,32 @@ +package org.gluu.service.cache; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import javax.enterprise.util.AnnotationLiteral; +import javax.inject.Qualifier; + +/** + * @author Yuriy Movchan Date: 11/12/2019 + */ +@Qualifier +@Retention(RUNTIME) +@Target({ TYPE, METHOD, FIELD }) +@Documented +public @interface LocalCache { + + final class Literal extends AnnotationLiteral implements LocalCache { + + public static final Literal INSTANCE = new Literal(); + + private static final long serialVersionUID = 1L; + + } + +} diff --git a/oxService/src/main/java/org/gluu/service/cache/MemcachedConfiguration.java b/core-cache/src/main/java/org/gluu/service/cache/MemcachedConfiguration.java similarity index 100% rename from oxService/src/main/java/org/gluu/service/cache/MemcachedConfiguration.java rename to core-cache/src/main/java/org/gluu/service/cache/MemcachedConfiguration.java index 4c1f8dc80..ce91b4341 100644 --- a/oxService/src/main/java/org/gluu/service/cache/MemcachedConfiguration.java +++ b/core-cache/src/main/java/org/gluu/service/cache/MemcachedConfiguration.java @@ -1,9 +1,9 @@ package org.gluu.service.cache; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - import java.io.Serializable; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + /** * @author yuriyz on 02/02/2017. diff --git a/oxService/src/main/java/org/gluu/service/cache/MemcachedConnectionFactoryType.java b/core-cache/src/main/java/org/gluu/service/cache/MemcachedConnectionFactoryType.java similarity index 100% rename from oxService/src/main/java/org/gluu/service/cache/MemcachedConnectionFactoryType.java rename to core-cache/src/main/java/org/gluu/service/cache/MemcachedConnectionFactoryType.java diff --git a/oxService/src/main/java/org/gluu/service/cache/MemcachedProvider.java b/core-cache/src/main/java/org/gluu/service/cache/MemcachedProvider.java similarity index 85% rename from oxService/src/main/java/org/gluu/service/cache/MemcachedProvider.java rename to core-cache/src/main/java/org/gluu/service/cache/MemcachedProvider.java index 25715e77d..52c785704 100644 --- a/oxService/src/main/java/org/gluu/service/cache/MemcachedProvider.java +++ b/core-cache/src/main/java/org/gluu/service/cache/MemcachedProvider.java @@ -4,6 +4,7 @@ import net.spy.memcached.internal.OperationFuture; import net.spy.memcached.ops.OperationStatus; import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; @@ -27,6 +28,10 @@ public class MemcachedProvider extends AbstractCacheProvider { public MemcachedProvider() { } + public void setCacheConfiguration(CacheConfiguration cacheConfiguration) { + this.cacheConfiguration = cacheConfiguration; + } + @PostConstruct public void init() { this.memcachedConfiguration = cacheConfiguration.getMemcachedConfiguration(); @@ -54,6 +59,11 @@ public void create() { } } + public void configure(CacheConfiguration cacheConfiguration) { + this.log = LoggerFactory.getLogger(MemcachedProvider.class); + this.cacheConfiguration = cacheConfiguration; + } + private void testConnection() { put(2, "connectionTest", "connectionTestValue"); if (!"connectionTestValue".equals(get("connectionTest"))) { @@ -61,6 +71,14 @@ private void testConnection() { } } + public boolean isConnected() { + put(2, "connectionTest", "connectionTestValue"); + if (!"connectionTestValue".equals(get("connectionTest"))) { + return false; + } + return true; + } + @PreDestroy public void destroy() { log.debug("Destroying MemcachedProvider"); @@ -78,6 +96,13 @@ public MemcachedClient getDelegate() { return client; } + @Override + public boolean hasKey(String key) { + Object value = get(key); + + return value != null; + } + @Override public Object get(String key) { try { diff --git a/core-cache/src/main/java/org/gluu/service/cache/NativePersistenceCacheEntity.java b/core-cache/src/main/java/org/gluu/service/cache/NativePersistenceCacheEntity.java new file mode 100644 index 000000000..7a5dc58e1 --- /dev/null +++ b/core-cache/src/main/java/org/gluu/service/cache/NativePersistenceCacheEntity.java @@ -0,0 +1,60 @@ +package org.gluu.service.cache; + +import org.gluu.persist.annotation.*; +import org.gluu.persist.model.base.Deletable; +import org.gluu.persist.model.base.DeletableEntity; + +import java.io.Serializable; +import java.util.Date; + +@DataEntry +@ObjectClass(value = "cache") +public class NativePersistenceCacheEntity extends DeletableEntity implements Serializable, Deletable { + + @Expiration + private Integer ttl; + @AttributeName(name = "uuid") + private String id; + @AttributeName(name = "iat") + private Date creationDate; + @AttributeName(name = "dat") + private String data; + + public Integer getTtl() { + return ttl; + } + + public void setTtl(Integer ttl) { + this.ttl = ttl; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Date getCreationDate() { + return creationDate; + } + + public void setCreationDate(Date creationDate) { + this.creationDate = creationDate; + } + + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + } + + @Override + public String toString() { + return "NativePersistenceCacheEntity [dn=" + getDn() + ", ttl=" + ttl + ", id=" + id + ", creationDate=" + creationDate + ", data=" + + data + "]"; + } +} diff --git a/oxService/src/main/java/org/gluu/service/cache/NativePersistenceCacheProvider.java b/core-cache/src/main/java/org/gluu/service/cache/NativePersistenceCacheProvider.java similarity index 52% rename from oxService/src/main/java/org/gluu/service/cache/NativePersistenceCacheProvider.java rename to core-cache/src/main/java/org/gluu/service/cache/NativePersistenceCacheProvider.java index 10647da5a..79478564d 100644 --- a/oxService/src/main/java/org/gluu/service/cache/NativePersistenceCacheProvider.java +++ b/core-cache/src/main/java/org/gluu/service/cache/NativePersistenceCacheProvider.java @@ -5,11 +5,14 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.gluu.persist.PersistenceEntryManager; +import org.gluu.persist.exception.EntryPersistenceException; +import org.gluu.persist.exception.operation.DuplicateEntryException; import org.gluu.persist.model.base.SimpleBranch; import org.gluu.search.filter.Filter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import java.io.ByteArrayInputStream; @@ -22,7 +25,8 @@ @ApplicationScoped public class NativePersistenceCacheProvider extends AbstractCacheProvider { - private final static Logger log = LoggerFactory.getLogger(NativePersistenceCacheProvider.class); + @Inject + private Logger log; @Inject private CacheConfiguration cacheConfiguration; @@ -32,14 +36,25 @@ public class NativePersistenceCacheProvider extends AbstractCacheProvider 0 ? expirationInSeconds : cacheConfiguration.getNativePersistenceConfiguration().getDefaultPutExpiration(); + + putImpl(key, object, creationDate, expirationInSeconds); + } - expirationInSeconds = expirationInSeconds > 0 ? expirationInSeconds : cacheConfiguration.getNativePersistenceConfiguration().getDefaultPutExpiration(); + private void putImpl(String key, Object object, Date creationDate, int expirationInSeconds) { + Calendar expirationDate = Calendar.getInstance(); + expirationDate.setTime(creationDate); + expirationDate.add(Calendar.SECOND, expirationInSeconds); - Calendar expirationDate = Calendar.getInstance(); - expirationDate.setTime(creationDate); - expirationDate.add(Calendar.SECOND, expirationInSeconds); + + String originalKey = key; - NativePersistenceCacheEntity entity = new NativePersistenceCacheEntity(); - entity.setData(asString(object)); - entity.setId(key); - entity.setDn(createDn(key)); - entity.setCreationDate(creationDate); - entity.setExpirationDate(expirationDate.getTime()); - entity.setDeletable(true); + key = hashKey(key); - silentlyRemoveEntityIfExists(entity.getDn()); - entryManager.persist(entity); + NativePersistenceCacheEntity entity = new NativePersistenceCacheEntity(); + entity.setTtl(expirationInSeconds); + entity.setData(asString(object)); + entity.setId(key); + entity.setDn(createDn(key)); + entity.setCreationDate(creationDate); + entity.setExpirationDate(expirationDate.getTime()); + entity.setDeletable(true); + + try { + if (attemptUpdateBeforeInsert) { + entryManager.merge(entity); + } else { + if (!skipRemoveBeforePut) { + silentlyRemoveEntityIfExists(entity.getDn()); + } + entryManager.persist(entity); + } + } catch (EntryPersistenceException e) { + if (e.getCause() instanceof DuplicateEntryException) { // on duplicate, remove entry and try to persist again + try { + silentlyRemoveEntityIfExists(entity.getDn()); + entryManager.persist(entity); + return; + } catch (Exception ex) { + log.error("Failed to retry put entry, key: " + originalKey + ", hashedKey: " + key + ", message: " + ex.getMessage(), ex); + } + } + + if (attemptUpdateBeforeInsert) { + try { + entryManager.persist(entity); + return; + } catch (Exception ex) { + log.error("Failed to retry put entry, key: " + originalKey + ", hashedKey: " + key + ", message: " + ex.getMessage(), ex); + } + } + + log.error("Failed to put entry, key: " + originalKey + ", hashedKey: " + key + ", message: " + e.getMessage(), e); } catch (Exception e) { - log.trace("Failed to put entry, key: " + originalKey + ", hashedKey: " + key + ", message: " + e.getMessage(), e); // log as trace since it is perfectly valid that entry is removed by timer for example + log.error("Failed to put entry, key: " + originalKey + ", hashedKey: " + key + ", message: " + e.getMessage(), e); // log as trace since it is perfectly valid that entry is removed by timer for example } - } + } private boolean silentlyRemoveEntityIfExists(String dn) { try { if (entryManager.find(NativePersistenceCacheEntity.class, dn) != null) { - entryManager.removeRecursively(dn); + entryManager.remove(dn, NativePersistenceCacheEntity.class); return true; } } catch (Exception e) { @@ -159,7 +237,7 @@ public void clear() { // TODO: Implement all specific application objects removal } - private static Object fromString(String s) { + private Object fromString(String s) { try { byte[] data = Base64.decodeBase64(s); ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(data)); @@ -171,12 +249,12 @@ private static Object fromString(String s) { IOUtils.closeQuietly(ois); } } catch (Exception e) { - log.error("Failed to deserizalize cache entity, data: " + s); + log.error("Failed to deserizalize cache entity, data: " + s, e); return null; } } - private static String asString(Object o) { + private String asString(Object o) { ObjectOutputStream oos = null; try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); @@ -185,7 +263,7 @@ private static String asString(Object o) { oos.close(); return Base64.encodeBase64String(baos.toByteArray()); } catch (Exception e) { - log.error("Failed to serizalize cache entity to string, object: " + 0); + log.error("Failed to serizalize cache entity to string, object: " + 0, e); return null; } finally { IOUtils.closeQuietly(oos); @@ -194,13 +272,18 @@ private static String asString(Object o) { @Override public void cleanup(final Date now) { - cleanup(now, cacheConfiguration.getNativePersistenceConfiguration().getDefaultCleanupBatchSize()); + NativePersistenceConfiguration nativePersistenceConfiguration = cacheConfiguration.getNativePersistenceConfiguration(); + if (!entryManager.hasExpirationSupport(nativePersistenceConfiguration.getBaseDn())) { + cleanup(now, cacheConfiguration.getNativePersistenceConfiguration().getDefaultCleanupBatchSize()); + } } public void cleanup(final Date now, int batchSize) { log.debug("Start NATIVE_PERSISTENCE clean up"); try { - Filter filter = Filter.createLessOrEqualFilter("oxAuthExpiration", entryManager.encodeTime(baseDn, now)); + Filter filter = Filter.createANDFilter( + Filter.createEqualityFilter("del", true), + Filter.createLessOrEqualFilter("exp", entryManager.encodeTime(baseDn, now))); final int removedCount = entryManager.remove(baseDn, NativePersistenceCacheEntity.class, filter, batchSize); log.debug("End NATIVE_PERSISTENCE clean up, items removed: " + removedCount); @@ -229,4 +312,11 @@ public void setBaseDn(String baseDn) { public void setCacheConfiguration(CacheConfiguration cacheConfiguration) { this.cacheConfiguration = cacheConfiguration; } + + public static void main(String[] args) { + NativePersistenceCacheProvider cp = new NativePersistenceCacheProvider(); + Object obj = cp.fromString("rO0ABXNyAClvcmcuZ2x1dS5veGF1dGgubW9kZWwuY29tbW9uLkNsaWVudFRva2Vuc/Aib54fThHVAgACTAAIY2xpZW50SWR0ABJMamF2YS9sYW5nL1N0cmluZztMAAt0b2tlbkhhc2hlc3QAD0xqYXZhL3V0aWwvU2V0O3hwdAApMTAwMS45MGQ0MGI2OS02ZDFmLTQxMmYtOTg5ZS00MThmN2E2Y2M1MTNzcgARamF2YS51dGlsLkhhc2hTZXS6RIWVlri3NAMAAHhwdwwAAAAQP0AAAAAAAAF0AEA3M2M1NDBhYjRlNzU2ZTk2ZjQ2NzU2ODZjNzU0ZDg1ZjZiOWExYmI0ZjI1ZWY5NTZjYmRkZTQ0NjlmZTA2OGVjeA=="); + + System.out.println(obj); + } } diff --git a/oxService/src/main/java/org/gluu/service/cache/NativePersistenceConfiguration.java b/core-cache/src/main/java/org/gluu/service/cache/NativePersistenceConfiguration.java similarity index 60% rename from oxService/src/main/java/org/gluu/service/cache/NativePersistenceConfiguration.java rename to core-cache/src/main/java/org/gluu/service/cache/NativePersistenceConfiguration.java index e258ca060..524ad832f 100644 --- a/oxService/src/main/java/org/gluu/service/cache/NativePersistenceConfiguration.java +++ b/core-cache/src/main/java/org/gluu/service/cache/NativePersistenceConfiguration.java @@ -1,11 +1,12 @@ package org.gluu.service.cache; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import java.io.Serializable; import javax.xml.bind.annotation.XmlElement; -import java.io.Serializable; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @JsonIgnoreProperties(ignoreUnknown = true) public class NativePersistenceConfiguration implements Serializable { @@ -14,7 +15,10 @@ public class NativePersistenceConfiguration implements Serializable { private int defaultPutExpiration = 60; // in seconds @XmlElement(name = "defaultCleanupBatchSize") - private int defaultCleanupBatchSize = 25; // 25 objects per iteration + private int defaultCleanupBatchSize = 1000; // 1000 objects per iteration + + @XmlElement(name = "deleteExpiredOnGetRequest") + private boolean deleteExpiredOnGetRequest = false; @JsonIgnore private String baseDn; @@ -35,7 +39,15 @@ public void setDefaultCleanupBatchSize(int defaultCleanupBatchSize) { this.defaultCleanupBatchSize = defaultCleanupBatchSize; } - public String getBaseDn() { + public boolean isDeleteExpiredOnGetRequest() { + return deleteExpiredOnGetRequest; + } + + public void setDeleteExpiredOnGetRequest(boolean deleteExpiredOnGetRequest) { + this.deleteExpiredOnGetRequest = deleteExpiredOnGetRequest; + } + + public String getBaseDn() { return baseDn; } @@ -44,10 +56,8 @@ public void setBaseDn(String baseDn) { } @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("NativePersistenceConfiguration [defaultPutExpiration=").append(defaultPutExpiration).append(", defaultCleanupBatchSize=") - .append(defaultCleanupBatchSize).append(", baseDn=").append(baseDn).append("]"); - return builder.toString(); - } + public String toString() { + return "NativePersistenceConfiguration [defaultPutExpiration=" + defaultPutExpiration + ", defaultCleanupBatchSize=" + + defaultCleanupBatchSize + ", deleteExpiredOnGetRequest=" + deleteExpiredOnGetRequest + ", baseDn=" + baseDn + "]"; + } } diff --git a/oxService/src/main/java/org/gluu/service/cache/RedisClusterProvider.java b/core-cache/src/main/java/org/gluu/service/cache/RedisClusterProvider.java similarity index 73% rename from oxService/src/main/java/org/gluu/service/cache/RedisClusterProvider.java rename to core-cache/src/main/java/org/gluu/service/cache/RedisClusterProvider.java index 21c5e6745..9230a4564 100644 --- a/oxService/src/main/java/org/gluu/service/cache/RedisClusterProvider.java +++ b/core-cache/src/main/java/org/gluu/service/cache/RedisClusterProvider.java @@ -1,19 +1,18 @@ package org.gluu.service.cache; -import java.io.IOException; -import java.io.Serializable; -import java.util.HashSet; -import java.util.Set; - import org.apache.commons.lang.SerializationUtils; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import redis.clients.jedis.HostAndPort; import redis.clients.jedis.JedisCluster; import redis.clients.jedis.JedisPoolConfig; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + /** * Important : keep it weld free. It's reused by oxd ! * @@ -33,16 +32,24 @@ public void create() { try { LOG.debug("Starting RedisClusterProvider ... configuration:" + getRedisConfiguration()); - JedisPoolConfig poolConfig = new JedisPoolConfig(); - poolConfig.setMaxTotal(1000); - poolConfig.setMinIdle(2); + JedisPoolConfig poolConfig = createPoolConfig(); + String password = redisConfiguration.getPassword(); + + if (redisConfiguration.getUseSSL()) { + RedisProviderFactory.setSSLSystemProperties(redisConfiguration); - pool = new JedisCluster(hosts(getRedisConfiguration().getServers()), poolConfig); + pool = new JedisCluster(hosts(getRedisConfiguration().getServers()), redisConfiguration.getConnectionTimeout(), + redisConfiguration.getSoTimeout(), redisConfiguration.getMaxRetryAttempts(), + password, UUID.randomUUID().toString(), poolConfig, true); + } else { + pool = new JedisCluster(hosts(getRedisConfiguration().getServers()), redisConfiguration.getConnectionTimeout(), + redisConfiguration.getSoTimeout(), redisConfiguration.getMaxRetryAttempts(), password, poolConfig); + } testConnection(); LOG.debug("RedisClusterProvider started."); } catch (Exception e) { - LOG.error("Failed to start RedisClusterProvider."); + LOG.error("Failed to start RedisClusterProvider.", e); throw new IllegalStateException("Error starting RedisClusterProvider", e); } } @@ -63,12 +70,7 @@ public static Set hosts(String servers) { public void destroy() { LOG.debug("Destroying RedisClusterProvider"); - try { - pool.close(); - } catch (IOException e) { - LOG.error("Failed to destroy RedisClusterProvider", e); - return; - } + pool.close(); LOG.debug("Destroyed RedisClusterProvider"); } @@ -78,6 +80,13 @@ public JedisCluster getDelegate() { return pool; } + @Override + public boolean hasKey(String key) { + Boolean hasKey = pool.exists(key); + + return Boolean.TRUE.equals(hasKey); + } + @Override public Object get(String key) { byte[] value = pool.get(key.getBytes()); @@ -110,4 +119,5 @@ public void remove(String key) { public void clear() { LOG.trace("clear not allowed for cluster deployments"); } + } diff --git a/core-cache/src/main/java/org/gluu/service/cache/RedisConfiguration.java b/core-cache/src/main/java/org/gluu/service/cache/RedisConfiguration.java new file mode 100644 index 000000000..bd4ac11b0 --- /dev/null +++ b/core-cache/src/main/java/org/gluu/service/cache/RedisConfiguration.java @@ -0,0 +1,198 @@ +package org.gluu.service.cache; + + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import java.io.Serializable; + +/** + * @author yuriyz on 02/23/2017. + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class RedisConfiguration implements Serializable { + + private static final long serialVersionUID = 5513197227832695471L; + + private RedisProviderType redisProviderType = RedisProviderType.STANDALONE; + + private String servers = "localhost:6379"; // server1:11211 server2:11211 + + private int defaultPutExpiration = 60; // in seconds + + private String sentinelMasterGroupName = ""; + + private String password; + + private Boolean useSSL = false; + + private String sslTrustStoreFilePath = ""; + + private String sslTrustStorePassword = ""; + + private String sslKeyStoreFilePath = ""; + + private String sslKeyStorePassword = ""; + + /** + * The cap on the number of "idle" instances in the pool. If maxIdle + * is set too low on heavily loaded systems it is possible you will see + * objects being destroyed and almost immediately new objects being created. + * This is a result of the active threads momentarily returning objects + * faster than they are requesting them, causing the number of idle + * objects to rise above maxIdle. The best value for maxIdle for heavily + * loaded system will vary but the default is a good starting point. + */ + private int maxIdleConnections = 10; + + private int maxTotalConnections = 500; + + private int connectionTimeout = 3000; + + /** + * With this option set to a non-zero timeout, a read() call on the InputStream associated with this Socket will block for only this amount of time. + * If the timeout expires, a java.net.SocketTimeoutException is raised, though the Socket is still valid. + * The option must be enabled prior to entering the blocking operation to have effect. The timeout must be > 0. + * A timeout of zero is interpreted as an infinite timeout. + */ + private int soTimeout = 3000; + + private int maxRetryAttempts = 5; + + public int getMaxIdleConnections() { + return maxIdleConnections; + } + + public void setMaxIdleConnections(int maxIdleConnections) { + this.maxIdleConnections = maxIdleConnections; + } + + public int getConnectionTimeout() { + return connectionTimeout; + } + + public void setConnectionTimeout(int connectionTimeout) { + this.connectionTimeout = connectionTimeout; + } + + public int getSoTimeout() { + return soTimeout; + } + + public void setSoTimeout(int soTimeout) { + this.soTimeout = soTimeout; + } + + public int getMaxRetryAttempts() { + return maxRetryAttempts; + } + + public void setMaxRetryAttempts(int maxRetryAttempts) { + this.maxRetryAttempts = maxRetryAttempts; + } + + public int getMaxTotalConnections() { + return maxTotalConnections; + } + + public void setMaxTotalConnections(int maxTotalConnections) { + this.maxTotalConnections = maxTotalConnections; + } + + public String getServers() { + return servers; + } + + public void setServers(String servers) { + this.servers = servers; + } + + public int getDefaultPutExpiration() { + return defaultPutExpiration; + } + + public void setDefaultPutExpiration(int defaultPutExpiration) { + this.defaultPutExpiration = defaultPutExpiration; + } + + public RedisProviderType getRedisProviderType() { + return redisProviderType; + } + + public void setRedisProviderType(RedisProviderType redisProviderType) { + this.redisProviderType = redisProviderType; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public Boolean getUseSSL() { + return useSSL != null ? useSSL : false; + } + + public void setUseSSL(Boolean useSSL) { + this.useSSL = useSSL; + } + + public String getSslTrustStoreFilePath() { + return sslTrustStoreFilePath; + } + + public void setSslTrustStoreFilePath(String sslTrustStoreFilePath) { + this.sslTrustStoreFilePath = sslTrustStoreFilePath; + } + + public String getSslTrustStorePassword() { + return sslTrustStorePassword; + } + + public void setSslTrustStorePassword(String sslTrustStorePassword) { + this.sslTrustStorePassword = sslTrustStorePassword; + } + + public String getSslKeyStoreFilePath() { + return sslKeyStoreFilePath; + } + + public void setSslKeyStoreFilePath(String sslKeyStoreFilePath) { + this.sslKeyStoreFilePath = sslKeyStoreFilePath; + } + + public String getSslKeyStorePassword() { + return sslKeyStorePassword; + } + + public void setSslKeyStorePassword(String sslKeyStorePassword) { + this.sslKeyStorePassword = sslKeyStorePassword; + } + + public String getSentinelMasterGroupName() { + return sentinelMasterGroupName; + } + + public void setSentinelMasterGroupName(String sentinelMasterGroupName) { + this.sentinelMasterGroupName = sentinelMasterGroupName; + } + + @Override + public String toString() { + return "RedisConfiguration{" + + "servers='" + servers + '\'' + + ", defaultPutExpiration=" + defaultPutExpiration + + ", redisProviderType=" + redisProviderType + + ", useSSL=" + useSSL + + ", sslTrustStoreFilePath=" + sslTrustStoreFilePath + + ", sslKeyStoreFilePath=" + sslKeyStoreFilePath + + ", sentinelMasterGroupName=" + sentinelMasterGroupName + + ", maxIdleConnections=" + maxIdleConnections + + ", maxTotalConnections=" + maxTotalConnections + + ", connectionTimeout=" + connectionTimeout + + ", soTimeout=" + soTimeout + + ", maxRetryAttempts=" + maxRetryAttempts + + '}'; + } +} diff --git a/oxService/src/main/java/org/gluu/service/cache/RedisProvider.java b/core-cache/src/main/java/org/gluu/service/cache/RedisProvider.java similarity index 79% rename from oxService/src/main/java/org/gluu/service/cache/RedisProvider.java rename to core-cache/src/main/java/org/gluu/service/cache/RedisProvider.java index cca38a76c..eb43cc6ef 100644 --- a/oxService/src/main/java/org/gluu/service/cache/RedisProvider.java +++ b/core-cache/src/main/java/org/gluu/service/cache/RedisProvider.java @@ -3,6 +3,7 @@ import org.apache.commons.lang.StringUtils; import org.gluu.util.security.StringEncrypter; import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; @@ -41,25 +42,33 @@ public void create() { RedisConfiguration redisConfiguration = cacheConfiguration.getRedisConfiguration(); decryptPassword(redisConfiguration); log.debug("Starting RedisProvider ... configuration:" + redisConfiguration); - defaultPutExpiration = redisConfiguration.getDefaultPutExpiration() > 0 ? redisConfiguration.getDefaultPutExpiration() : DEFAULT_PUT_EXPIRATION_IN_SECONDS; - redisProvider = RedisProviderFactory.create(cacheConfiguration.getRedisConfiguration()); redisProvider.create(); - log.debug("RedisProvider started."); } catch (Exception e) { log.error("Failed to start RedisProvider."); + log.error("Log Error",e); throw new IllegalStateException("Error starting RedisProvider", e); } } + public void configure(CacheConfiguration cacheConfiguration, StringEncrypter stringEncrypter) { + this.log = LoggerFactory.getLogger(RedisProvider.class); + this.cacheConfiguration = cacheConfiguration; + this.stringEncrypter = stringEncrypter; + } + + public void setCacheConfiguration(CacheConfiguration cacheConfiguration){ + this.cacheConfiguration=cacheConfiguration; + } + private void decryptPassword(RedisConfiguration redisConfiguration) { try { String encryptedPassword = redisConfiguration.getPassword(); if (StringUtils.isNotBlank(encryptedPassword)) { - redisConfiguration.setDecryptedPassword(stringEncrypter.decrypt(encryptedPassword)); + redisConfiguration.setPassword(stringEncrypter.decrypt(encryptedPassword)); log.trace("Decrypted redis password successfully."); } } catch (StringEncrypter.EncryptionException e) { @@ -67,6 +76,10 @@ private void decryptPassword(RedisConfiguration redisConfiguration) { } } + public boolean isConnected(){ + return redisProvider.isConnected(); + } + @PreDestroy public void destroy() { @@ -80,6 +93,14 @@ public AbstractRedisProvider getDelegate() { return redisProvider; } + @Override + public boolean hasKey(String key) { + if (key == null) { + return false; + } + return redisProvider.hasKey(key); + } + @Override public Object get(String key) { if (key == null) { diff --git a/core-cache/src/main/java/org/gluu/service/cache/RedisProviderFactory.java b/core-cache/src/main/java/org/gluu/service/cache/RedisProviderFactory.java new file mode 100644 index 000000000..ea19df735 --- /dev/null +++ b/core-cache/src/main/java/org/gluu/service/cache/RedisProviderFactory.java @@ -0,0 +1,96 @@ +package org.gluu.service.cache; + +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManagerFactory; +import java.io.FileInputStream; +import java.security.KeyStore; +import java.security.SecureRandom; + +/** + * Important : keep it weld free. It's reused by oxd ! + * + * @author yuriyz + */ +public final class RedisProviderFactory { + + private static final Logger LOG = LoggerFactory.getLogger(RedisProviderFactory.class); + + private RedisProviderFactory() { + } + + public static AbstractRedisProvider create(RedisConfiguration redisConfiguration) { + try { + LOG.debug("Creating RedisProvider ... configuration:" + redisConfiguration); + + switch (redisConfiguration.getRedisProviderType()) { + case STANDALONE: + return new RedisStandaloneProvider(redisConfiguration); + case CLUSTER: + return new RedisClusterProvider(redisConfiguration); + case SHARDED: + return new RedisShardedProvider(redisConfiguration); + case SENTINEL: + return new RedisSentinelProvider(redisConfiguration); + default: + LOG.error("Failed to create RedisProvider. RedisProviderType is not supported by current version of oxcore: " + + redisConfiguration.getRedisProviderType() + ", redisConfiguration:" + redisConfiguration); + throw new RuntimeException( + "RedisProviderType is not supported by current version of oxcore: " + redisConfiguration.getRedisProviderType()); + } + } catch (Exception e) { + LOG.error("Failed to create RedisProvider."); + throw new RuntimeException("Error creating RedisProvider", e); + } + } + + public static void destroy(AbstractRedisProvider provider) { + if (provider != null) { + provider.destroy(); + } + } + + public static void destroySilently(AbstractRedisProvider provider) { + try { + destroy(provider); + } catch (Exception e) { + LOG.error("Failed to destroy redis provider.", e); + } + } + + public static SSLSocketFactory createSslSocketFactory(RedisConfiguration redisConfiguration) throws Exception { + KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); + trustStore.load(new FileInputStream(redisConfiguration.getSslTrustStoreFilePath()), + redisConfiguration.getSslTrustStorePassword().toCharArray()); + TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + trustManagerFactory.init(trustStore); + + KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); + keyStore.load(new FileInputStream(redisConfiguration.getSslKeyStoreFilePath()), + redisConfiguration.getSslKeyStorePassword().toCharArray()); + KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + keyManagerFactory.init(keyStore, redisConfiguration.getSslKeyStorePassword().toCharArray()); + + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom()); + + return sslContext.getSocketFactory(); + } + + public static void setSSLSystemProperties(RedisConfiguration redisConfiguration) { + if (StringUtils.isNotBlank(redisConfiguration.getSslKeyStoreFilePath())) { + System.setProperty("javax.net.ssl.keyStore", redisConfiguration.getSslKeyStoreFilePath()); + System.setProperty("javax.net.ssl.keyStorePassword", redisConfiguration.getSslKeyStorePassword()); + } + + if (StringUtils.isNotBlank(redisConfiguration.getSslTrustStoreFilePath())) { + System.setProperty("javax.net.ssl.trustStore", redisConfiguration.getSslTrustStoreFilePath()); + System.setProperty("javax.net.ssl.trustStorePassword", redisConfiguration.getSslTrustStorePassword()); + } + } +} diff --git a/oxService/src/main/java/org/gluu/service/cache/RedisProviderType.java b/core-cache/src/main/java/org/gluu/service/cache/RedisProviderType.java similarity index 78% rename from oxService/src/main/java/org/gluu/service/cache/RedisProviderType.java rename to core-cache/src/main/java/org/gluu/service/cache/RedisProviderType.java index be5a3f1ad..fc6fd20ce 100644 --- a/oxService/src/main/java/org/gluu/service/cache/RedisProviderType.java +++ b/core-cache/src/main/java/org/gluu/service/cache/RedisProviderType.java @@ -7,5 +7,5 @@ */ @XmlEnum(String.class) public enum RedisProviderType { - STANDALONE, CLUSTER, SHARDED + STANDALONE, CLUSTER, SHARDED, SENTINEL } diff --git a/core-cache/src/main/java/org/gluu/service/cache/RedisSentinelProvider.java b/core-cache/src/main/java/org/gluu/service/cache/RedisSentinelProvider.java new file mode 100644 index 000000000..3cd572188 --- /dev/null +++ b/core-cache/src/main/java/org/gluu/service/cache/RedisSentinelProvider.java @@ -0,0 +1,123 @@ +package org.gluu.service.cache; + +import org.apache.commons.lang.SerializationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import redis.clients.jedis.*; + +import java.io.Serializable; + +import static org.gluu.service.cache.RedisClusterProvider.hosts; + +/** + * Important : keep it weld free. It's reused by oxd ! + * + * @author Yuriy Zabrovarnyy + */ +public class RedisSentinelProvider extends AbstractRedisProvider { + + private static final Logger LOG = LoggerFactory.getLogger(RedisSentinelProvider.class); + + private JedisSentinelPool pool; + + public RedisSentinelProvider(RedisConfiguration redisConfiguration) { + super(redisConfiguration); + } + + public void create() { + try { + LOG.debug("Starting RedisSentinelProvider ... configuration:" + getRedisConfiguration()); + + String password = redisConfiguration.getPassword(); + JedisPoolConfig poolConfig = createPoolConfig(); + JedisClientConfig jedisClientConfig; + + if (redisConfiguration.getUseSSL()) { + RedisProviderFactory.setSSLSystemProperties(redisConfiguration); + jedisClientConfig = DefaultJedisClientConfig.builder().ssl(true).password(password).build(); + } else { + jedisClientConfig = DefaultJedisClientConfig.builder().ssl(false).password(password).build(); + } + + pool = new JedisSentinelPool(getRedisConfiguration().getSentinelMasterGroupName(), + hosts(getRedisConfiguration().getServers()), poolConfig, jedisClientConfig, jedisClientConfig); + + testConnection(); + LOG.debug("RedisSentinelProvider started."); + } catch (Exception e) { + LOG.error("Failed to start RedisSentinelProvider.", e); + throw new IllegalStateException("Error starting RedisSentinelProvider", e); + } + } + + public void destroy() { + LOG.debug("Destroying RedisSentinelProvider"); + + try { + pool.close(); + } catch (Exception e) { + LOG.error("Failed to destroy RedisSentinelProvider", e); + return; + } + + LOG.debug("Destroyed RedisSentinelProvider"); + } + + @Override + public JedisSentinelPool getDelegate() { + return pool; + } + + @Override + public boolean hasKey(String key) { + try (final Jedis resource = pool.getResource()) { + Boolean hasKey = resource.exists(key); + + return Boolean.TRUE.equals(hasKey); + } + } + + @Override + public Object get(String key) { + try (final Jedis resource = pool.getResource()) { + byte[] value = resource.get(key.getBytes()); + Object deserialized = null; + if (value != null && value.length > 0) { + deserialized = SerializationUtils.deserialize(value); + } + return deserialized; + } + } + + @Override + public void put(int expirationInSeconds, String key, Object object) { + try (final Jedis resource = pool.getResource()) { + String status = resource.setex(key.getBytes(), expirationInSeconds, SerializationUtils.serialize((Serializable) object)); + LOG.trace("put - key: " + key + ", status: " + status); + } + } + + @Override + public void put(String key, Object object) { + try (final Jedis resource = pool.getResource()) { + String status = resource.set(key.getBytes(), SerializationUtils.serialize((Serializable) object)); + LOG.trace("put - key: " + key + ", status: " + status); + } + } + + @Override + public void remove(String key) { + try (final Jedis resource = pool.getResource()) { + Long entriesRemoved = resource.del(key.getBytes()); + LOG.trace("remove - key: " + key + ", entriesRemoved: " + entriesRemoved); + } + } + + @Override + public void clear() { + try (final Jedis resource = pool.getResource()) { + resource.flushAll(); + LOG.trace("clear"); + } + } +} diff --git a/oxService/src/main/java/org/gluu/service/cache/RedisSetParams.java b/core-cache/src/main/java/org/gluu/service/cache/RedisSetParams.java similarity index 98% rename from oxService/src/main/java/org/gluu/service/cache/RedisSetParams.java rename to core-cache/src/main/java/org/gluu/service/cache/RedisSetParams.java index a3f51125a..22cb32a88 100644 --- a/oxService/src/main/java/org/gluu/service/cache/RedisSetParams.java +++ b/core-cache/src/main/java/org/gluu/service/cache/RedisSetParams.java @@ -3,7 +3,7 @@ import java.util.ArrayList; import redis.clients.jedis.params.Params; -import redis.clients.util.SafeEncoder; +import redis.clients.jedis.util.SafeEncoder; /** * Taken from here diff --git a/oxService/src/main/java/org/gluu/service/cache/RedisShardedProvider.java b/core-cache/src/main/java/org/gluu/service/cache/RedisShardedProvider.java similarity index 85% rename from oxService/src/main/java/org/gluu/service/cache/RedisShardedProvider.java rename to core-cache/src/main/java/org/gluu/service/cache/RedisShardedProvider.java index b69e754d6..e25fd6564 100644 --- a/oxService/src/main/java/org/gluu/service/cache/RedisShardedProvider.java +++ b/core-cache/src/main/java/org/gluu/service/cache/RedisShardedProvider.java @@ -2,16 +2,15 @@ import org.apache.commons.lang.SerializationUtils; import org.apache.commons.lang.StringUtils; +import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.apache.http.conn.ssl.DefaultHostnameVerifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import redis.clients.jedis.JedisPoolConfig; import redis.clients.jedis.JedisShardInfo; import redis.clients.jedis.ShardedJedis; import redis.clients.jedis.ShardedJedisPool; import javax.net.ssl.SSLParameters; -import java.io.File; import java.io.Serializable; import java.util.ArrayList; import java.util.List; @@ -35,8 +34,9 @@ public void create() { try { LOG.debug("Starting RedisShardedProvider ... configuration:" + redisConfiguration); - JedisPoolConfig poolConfig = new JedisPoolConfig(); - poolConfig.setMaxTotal(1000); + GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig<>(); + poolConfig.setMaxTotal(redisConfiguration.getMaxTotalConnections()); + poolConfig.setMaxIdle(redisConfiguration.getMaxIdleConnections()); poolConfig.setMinIdle(2); pool = new ShardedJedisPool(poolConfig, shards(redisConfiguration)); @@ -44,7 +44,7 @@ public void create() { testConnection(); LOG.debug("RedisShardedProvider started."); } catch (Exception e) { - LOG.error("Failed to start RedisShardedProvider."); + LOG.error("Failed to start RedisShardedProvider.", e); throw new IllegalStateException("Error starting RedisShardedProvider", e); } } @@ -63,9 +63,10 @@ private static List shards(RedisConfiguration configuration) { try { final JedisShardInfo shardInfo; if (configuration.getUseSSL()) { - if (StringUtils.isNotBlank(configuration.getSslTrustStoreFilePath())) { + if (StringUtils.isNotBlank(configuration.getSslTrustStoreFilePath()) + && StringUtils.isNotBlank(configuration.getSslKeyStoreFilePath())) { shardInfo = new JedisShardInfo(host, port, true, - RedisProviderFactory.createTrustStoreSslSocketFactory(new File(configuration.getSslTrustStoreFilePath())), + RedisProviderFactory.createSslSocketFactory(configuration), new SSLParameters(), new DefaultHostnameVerifier()); } else { shardInfo = new JedisShardInfo(host, port, true); @@ -97,6 +98,15 @@ public ShardedJedisPool getDelegate() { return pool; } + @Override + public boolean hasKey(String key) { + try (final ShardedJedis resource = pool.getResource()) { + Boolean hasKey = resource.exists(key); + + return Boolean.TRUE.equals(hasKey); + } + } + @Override public Object get(String key) { ShardedJedis jedis = pool.getResource(); diff --git a/oxService/src/main/java/org/gluu/service/cache/RedisStandaloneProvider.java b/core-cache/src/main/java/org/gluu/service/cache/RedisStandaloneProvider.java similarity index 66% rename from oxService/src/main/java/org/gluu/service/cache/RedisStandaloneProvider.java rename to core-cache/src/main/java/org/gluu/service/cache/RedisStandaloneProvider.java index 0910d056f..d980ba62a 100644 --- a/oxService/src/main/java/org/gluu/service/cache/RedisStandaloneProvider.java +++ b/core-cache/src/main/java/org/gluu/service/cache/RedisStandaloneProvider.java @@ -5,11 +5,14 @@ import org.apache.http.conn.ssl.DefaultHostnameVerifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import redis.clients.jedis.*; +import redis.clients.jedis.HostAndPort; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; import javax.annotation.PreDestroy; import javax.net.ssl.SSLParameters; -import java.io.File; +import javax.net.ssl.SSLSocketFactory; import java.io.Serializable; /** @@ -22,7 +25,6 @@ public class RedisStandaloneProvider extends AbstractRedisProvider { private static final Logger LOG = LoggerFactory.getLogger(RedisStandaloneProvider.class); private JedisPool pool; - public RedisStandaloneProvider(RedisConfiguration redisConfiguratio) { super(redisConfiguratio); } @@ -31,39 +33,29 @@ public void create() { LOG.debug("Starting RedisStandaloneProvider ..."); try { - JedisPoolConfig poolConfig = new JedisPoolConfig(); - poolConfig.setMaxTotal(1000); - poolConfig.setMinIdle(2); + JedisPoolConfig poolConfig = createPoolConfig(); HostAndPort hostAndPort = RedisClusterProvider.hosts(redisConfiguration.getServers()).iterator().next(); - + String password = redisConfiguration.getPassword(); if (redisConfiguration.getUseSSL()) { - if (StringUtils.isNotBlank(redisConfiguration.getSslTrustStoreFilePath())) { - if (StringUtils.isBlank(redisConfiguration.getDecryptedPassword())) { - pool = new JedisPool(poolConfig, hostAndPort.getHost(), hostAndPort.getPort(), true, - RedisProviderFactory.createTrustStoreSslSocketFactory(new File(redisConfiguration.getSslTrustStoreFilePath())), new SSLParameters(), new DefaultHostnameVerifier()); - } else { - pool = new JedisPool(poolConfig, hostAndPort.getHost(), hostAndPort.getPort(), Protocol.DEFAULT_TIMEOUT, redisConfiguration.getDecryptedPassword(), true, - RedisProviderFactory.createTrustStoreSslSocketFactory(new File(redisConfiguration.getSslTrustStoreFilePath())), new SSLParameters(), new DefaultHostnameVerifier()); - } + if (StringUtils.isNotBlank(redisConfiguration.getSslTrustStoreFilePath()) + && StringUtils.isNotBlank(redisConfiguration.getSslKeyStoreFilePath())) { + SSLSocketFactory sslSocketFactory = RedisProviderFactory.createSslSocketFactory(redisConfiguration); + + pool = new JedisPool(poolConfig, hostAndPort.getHost(), hostAndPort.getPort(), true, + sslSocketFactory, new SSLParameters(), new DefaultHostnameVerifier()); } else { - if (StringUtils.isBlank(redisConfiguration.getDecryptedPassword())) { - pool = new JedisPool(poolConfig, hostAndPort.getHost(), hostAndPort.getPort(), true); - } else { - pool = new JedisPool(poolConfig, hostAndPort.getHost(), hostAndPort.getPort(), Protocol.DEFAULT_TIMEOUT, redisConfiguration.getDecryptedPassword(), true); - } + pool = new JedisPool(poolConfig, hostAndPort.getHost(), hostAndPort.getPort(), + redisConfiguration.getConnectionTimeout(), password, true); } } else { - if (StringUtils.isBlank(redisConfiguration.getDecryptedPassword())) { - pool = new JedisPool(poolConfig, hostAndPort.getHost(), hostAndPort.getPort()); - } else { - pool = new JedisPool(poolConfig, hostAndPort.getHost(), hostAndPort.getPort(), Protocol.DEFAULT_TIMEOUT, redisConfiguration.getDecryptedPassword()); - } + pool = new JedisPool(poolConfig, hostAndPort.getHost(), hostAndPort.getPort(), redisConfiguration.getConnectionTimeout(), password); } testConnection(); LOG.debug("RedisStandaloneProvider started."); } catch (Exception e) { + LOG.error("Problems connecting with Redis", e); throw new IllegalStateException("Error starting RedisStandaloneProvider", e); } } @@ -82,6 +74,13 @@ public JedisPool getDelegate() { return pool; } + @Override + public boolean hasKey(String key) { + Boolean hasKey = pool.getResource().exists(key); + + return Boolean.TRUE.equals(hasKey); + } + @Override public Object get(String key) { Jedis jedis = pool.getResource(); diff --git a/core-cache/src/main/java/org/gluu/service/cache/StandaloneCacheProviderFactory.java b/core-cache/src/main/java/org/gluu/service/cache/StandaloneCacheProviderFactory.java new file mode 100644 index 000000000..209a0e709 --- /dev/null +++ b/core-cache/src/main/java/org/gluu/service/cache/StandaloneCacheProviderFactory.java @@ -0,0 +1,88 @@ +package org.gluu.service.cache; + +import org.gluu.persist.PersistenceEntryManager; +import org.gluu.util.StringHelper; +import org.gluu.util.security.StringEncrypter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Yuriy Movchan Date: 01/15/2020 + */ +public class StandaloneCacheProviderFactory { + + private static final Logger LOG = LoggerFactory.getLogger(StandaloneCacheProviderFactory.class); + + private PersistenceEntryManager entryManager; + private StringEncrypter stringEncrypter; + + public StandaloneCacheProviderFactory(PersistenceEntryManager entryManager, StringEncrypter stringEncrypter) { + this.entryManager = entryManager; + this.stringEncrypter = stringEncrypter; + } + + public CacheProvider getCacheProvider(CacheConfiguration cacheConfiguration) { + CacheProviderType cacheProviderType = cacheConfiguration.getCacheProviderType(); + + if (cacheProviderType == null) { + LOG.error("Failed to initialize cacheProvider, cacheProviderType is null. Fallback to IN_MEMORY type."); + cacheProviderType = CacheProviderType.IN_MEMORY; + } + + // Create bean + AbstractCacheProvider cacheProvider = null; + switch (cacheProviderType) { + case IN_MEMORY: + InMemoryCacheProvider inMemoryCacheProvider = new InMemoryCacheProvider(); + inMemoryCacheProvider.configure(cacheConfiguration); + inMemoryCacheProvider.init(); + + cacheProvider = inMemoryCacheProvider; + break; + case MEMCACHED: + MemcachedProvider memcachedProvider = new MemcachedProvider(); + memcachedProvider.configure(cacheConfiguration); + memcachedProvider.init(); + + cacheProvider = memcachedProvider; + break; + case REDIS: + if (stringEncrypter == null) { + throw new RuntimeException("Factory is not initialized properly. stringEncrypter is not specified"); + } + + RedisProvider redisProvider = new RedisProvider(); + redisProvider.configure(cacheConfiguration, stringEncrypter); + redisProvider.init(); + + cacheProvider = redisProvider; + break; + case NATIVE_PERSISTENCE: + if (entryManager == null) { + throw new RuntimeException("Factory is not initialized properly. entryManager is not specified"); + } + + NativePersistenceCacheProvider nativePersistenceCacheProvider = new NativePersistenceCacheProvider(); + nativePersistenceCacheProvider.configure(cacheConfiguration, entryManager); + + // TODO: Remove after configuration fix + if (StringHelper.isEmpty(cacheConfiguration.getNativePersistenceConfiguration().getBaseDn())) { + cacheConfiguration.getNativePersistenceConfiguration().setBaseDn("o=gluu"); + } + + nativePersistenceCacheProvider.init(); + + cacheProvider = nativePersistenceCacheProvider; + break; + } + + if (cacheProvider == null) { + throw new RuntimeException("Failed to initialize cacheProvider, cacheProviderType is unsupported: " + cacheProviderType); + } + + cacheProvider.create(); + + return cacheProvider; + } + +} diff --git a/persistence-cdi/src/main/resources/META-INF/beans.xml b/core-cache/src/main/resources/META-INF/beans.xml similarity index 100% rename from persistence-cdi/src/main/resources/META-INF/beans.xml rename to core-cache/src/main/resources/META-INF/beans.xml diff --git a/persistence-standalone/pom.xml b/core-cdi/pom.xml similarity index 64% rename from persistence-standalone/pom.xml rename to core-cdi/pom.xml index 1da83e906..91dbff937 100644 --- a/persistence-standalone/pom.xml +++ b/core-cdi/pom.xml @@ -2,14 +2,13 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.gluu - oxcore-persistence-standalone - Persistence standalone services + oxcore-cdi + Reusable CDI classes which not depend on specific framework org.gluu oxcore - 4.0.0-SNAPSHOT + 4.5.6-SNAPSHOT @@ -31,24 +30,25 @@ + - org.gluu - oxcore-persistence-cdi - ${project.version} + org.slf4j + slf4j-api + provided + + javax.enterprise cdi-api + provided + + - org.reflections - reflections + org.quartz-scheduler + quartz - - com.google.guava - guava - 20.0 - \ No newline at end of file diff --git a/oxService/src/main/java/org/gluu/service/cdi/async/Asynchronous.java b/core-cdi/src/main/java/org/gluu/service/cdi/async/Asynchronous.java similarity index 100% rename from oxService/src/main/java/org/gluu/service/cdi/async/Asynchronous.java rename to core-cdi/src/main/java/org/gluu/service/cdi/async/Asynchronous.java diff --git a/oxService/src/main/java/org/gluu/service/cdi/event/Scheduled.java b/core-cdi/src/main/java/org/gluu/service/cdi/event/Scheduled.java similarity index 100% rename from oxService/src/main/java/org/gluu/service/cdi/event/Scheduled.java rename to core-cdi/src/main/java/org/gluu/service/cdi/event/Scheduled.java diff --git a/oxService/src/main/java/org/gluu/service/timer/event/TimerEvent.java b/core-cdi/src/main/java/org/gluu/service/timer/event/TimerEvent.java similarity index 100% rename from oxService/src/main/java/org/gluu/service/timer/event/TimerEvent.java rename to core-cdi/src/main/java/org/gluu/service/timer/event/TimerEvent.java diff --git a/oxService/src/main/java/org/gluu/service/timer/schedule/JobShedule.java b/core-cdi/src/main/java/org/gluu/service/timer/schedule/JobShedule.java similarity index 100% rename from oxService/src/main/java/org/gluu/service/timer/schedule/JobShedule.java rename to core-cdi/src/main/java/org/gluu/service/timer/schedule/JobShedule.java diff --git a/oxService/src/main/java/org/gluu/service/timer/schedule/TimerSchedule.java b/core-cdi/src/main/java/org/gluu/service/timer/schedule/TimerSchedule.java similarity index 100% rename from oxService/src/main/java/org/gluu/service/timer/schedule/TimerSchedule.java rename to core-cdi/src/main/java/org/gluu/service/timer/schedule/TimerSchedule.java diff --git a/persistence-couchbase/src/main/resources/META-INF/beans.xml b/core-cdi/src/main/resources/META-INF/beans.xml similarity index 100% rename from persistence-couchbase/src/main/resources/META-INF/beans.xml rename to core-cdi/src/main/resources/META-INF/beans.xml diff --git a/core-document-store/pom.xml b/core-document-store/pom.xml new file mode 100644 index 000000000..65fe04010 --- /dev/null +++ b/core-document-store/pom.xml @@ -0,0 +1,112 @@ + + + 4.0.0 + oxcore-document-store + Caches support + + + org.gluu + oxcore + 4.5.6-SNAPSHOT + + + + ${maven.min-version} + + + + + + src/main/resources + true + + **/*.xml + **/services/* + **/*.properties + + + + + + src/test/resources + true + + **/*.xml + **/services/* + **/*.properties + + + + + + + + + org.gluu + oxcore-util + ${project.version} + + + org.gluu + gluu-orm-core + ${project.version} + + + org.gluu + gluu-orm-annotation + ${project.version} + + + + javax.enterprise + cdi-api + provided + + + + javax.inject + javax.inject + + + + + javax.jcr + jcr + + + org.apache.jackrabbit + jackrabbit-core + + + org.apache.jackrabbit + jackrabbit-jcr-rmi + + + org.apache.jackrabbit + jackrabbit-webdav + + + com.github.lookfirst + sardine + + + + + com.fasterxml.jackson.core + jackson-annotations + + + + + org.testng + testng + + + javax.annotation + javax.annotation-api + + + + \ No newline at end of file diff --git a/core-document-store/src/main/java/org/gluu/service/document/store/LocalDocumentStore.java b/core-document-store/src/main/java/org/gluu/service/document/store/LocalDocumentStore.java new file mode 100644 index 000000000..f637652c4 --- /dev/null +++ b/core-document-store/src/main/java/org/gluu/service/document/store/LocalDocumentStore.java @@ -0,0 +1,32 @@ +package org.gluu.service.document.store; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import javax.enterprise.util.AnnotationLiteral; +import javax.inject.Qualifier; + +/** + * @author Yuriy Movchan on 04/10/2020 + */ +@Qualifier +@Retention(RUNTIME) +@Target({ TYPE, METHOD, FIELD }) +@Documented +public @interface LocalDocumentStore { + + final class Literal extends AnnotationLiteral implements LocalDocumentStore { + + public static final Literal INSTANCE = new Literal(); + + private static final long serialVersionUID = 1L; + + } + +} diff --git a/core-document-store/src/main/java/org/gluu/service/document/store/StandaloneDocumentStoreProviderFactory.java b/core-document-store/src/main/java/org/gluu/service/document/store/StandaloneDocumentStoreProviderFactory.java new file mode 100644 index 000000000..c1bb573b3 --- /dev/null +++ b/core-document-store/src/main/java/org/gluu/service/document/store/StandaloneDocumentStoreProviderFactory.java @@ -0,0 +1,96 @@ +package org.gluu.service.document.store; + +import org.gluu.persist.PersistenceEntryManager; +import org.gluu.service.document.store.conf.DocumentStoreConfiguration; +import org.gluu.service.document.store.conf.DocumentStoreType; +import org.gluu.service.document.store.provider.DBDocumentStoreProvider; +import org.gluu.service.document.store.provider.DocumentStoreProvider; +import org.gluu.service.document.store.provider.JcaDocumentStoreProvider; +import org.gluu.service.document.store.provider.LocalDocumentStoreProvider; +import org.gluu.service.document.store.provider.WebDavDocumentStoreProvider; +import org.gluu.util.security.StringEncrypter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Yuriy Movchan on 04/10/2020 + */ +public class StandaloneDocumentStoreProviderFactory { + + private static final Logger LOG = LoggerFactory.getLogger(StandaloneDocumentStoreProviderFactory.class); + + private StringEncrypter stringEncrypter; + private PersistenceEntryManager persistenceEntryManager; + + public StandaloneDocumentStoreProviderFactory() { + } + + public StandaloneDocumentStoreProviderFactory(StringEncrypter stringEncrypter) { + this.stringEncrypter = stringEncrypter; + } + + public StandaloneDocumentStoreProviderFactory(PersistenceEntryManager persistenceEntryManager) { + this.persistenceEntryManager = persistenceEntryManager; + } + + public DocumentStoreProvider getDocumentStoreProvider(DocumentStoreConfiguration documentStoreConfiguration) { + DocumentStoreType documentStoreType = documentStoreConfiguration.getDocumentStoreType(); + + if (documentStoreType == null) { + LOG.error("Failed to initialize documentStoreProvider, documentStoreProviderType is null. Fallback to LOCAL type."); + documentStoreType = DocumentStoreType.LOCAL; + } + + // Create bean + DocumentStoreProvider documentStoreProvider = null; + switch (documentStoreType) { + case LOCAL: + LocalDocumentStoreProvider localDocumentStoreProvider = new LocalDocumentStoreProvider(); + localDocumentStoreProvider.configure(documentStoreConfiguration); + localDocumentStoreProvider.init(); + + documentStoreProvider = localDocumentStoreProvider; + break; + case JCA: + if (stringEncrypter == null) { + throw new RuntimeException("Factory is not initialized properly. stringEncrypter is not specified"); + } + + JcaDocumentStoreProvider jcaDocumentStoreProvider = new JcaDocumentStoreProvider(); + jcaDocumentStoreProvider.configure(documentStoreConfiguration, stringEncrypter); + jcaDocumentStoreProvider.init(); + + documentStoreProvider = jcaDocumentStoreProvider; + break; + case WEB_DAV: + if (stringEncrypter == null) { + throw new RuntimeException("Factory is not initialized properly. stringEncrypter is not specified"); + } + + WebDavDocumentStoreProvider webDavDocumentStoreProvider = new WebDavDocumentStoreProvider(); + webDavDocumentStoreProvider.configure(documentStoreConfiguration, stringEncrypter); + webDavDocumentStoreProvider.init(); + + documentStoreProvider = webDavDocumentStoreProvider; + break; + case DB: + DBDocumentStoreProvider dbDocumentStoreProvider = new DBDocumentStoreProvider(); + dbDocumentStoreProvider.configure(documentStoreConfiguration, persistenceEntryManager); + dbDocumentStoreProvider.init(); + + documentStoreProvider = dbDocumentStoreProvider; + break; + } + + + if (documentStoreProvider == null) { + throw new RuntimeException( + "Failed to initialize documentStoreProvider, documentStoreProviderType is unsupported: " + documentStoreType); + } + + documentStoreProvider.create(); + + return documentStoreProvider; + } + +} diff --git a/core-document-store/src/main/java/org/gluu/service/document/store/conf/DBDocumentStoreConfiguration.java b/core-document-store/src/main/java/org/gluu/service/document/store/conf/DBDocumentStoreConfiguration.java new file mode 100644 index 000000000..1dbd11b05 --- /dev/null +++ b/core-document-store/src/main/java/org/gluu/service/document/store/conf/DBDocumentStoreConfiguration.java @@ -0,0 +1,20 @@ +package org.gluu.service.document.store.conf; + +import java.io.Serializable; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +/** + * @author shekhar L. on 27/04/2022 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class DBDocumentStoreConfiguration implements Serializable { + + private static final long serialVersionUID = 3380170170265842538L; + + @Override + public String toString() { + return "DBDocumentStoreConfiguration []"; + } + +} diff --git a/core-document-store/src/main/java/org/gluu/service/document/store/conf/DocumentStoreConfiguration.java b/core-document-store/src/main/java/org/gluu/service/document/store/conf/DocumentStoreConfiguration.java new file mode 100644 index 000000000..54d1aa36e --- /dev/null +++ b/core-document-store/src/main/java/org/gluu/service/document/store/conf/DocumentStoreConfiguration.java @@ -0,0 +1,72 @@ +package org.gluu.service.document.store.conf; + +import java.io.Serializable; + +import javax.enterprise.inject.Vetoed; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +/** + * @author Yuriy Movchan on 04/10/2020 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@Vetoed +public class DocumentStoreConfiguration implements Serializable { + + private static final long serialVersionUID = 2519892725606554887L; + + private DocumentStoreType documentStoreType; + + private LocalDocumentStoreConfiguration localConfiguration; + + private JcaDocumentStoreConfiguration jcaConfiguration; + + private WebDavDocumentStoreConfiguration webDavConfiguration; + private DBDocumentStoreConfiguration dbConfiguration; + + public DocumentStoreType getDocumentStoreType() { + return documentStoreType; + } + + public void setDocumentStoreType(DocumentStoreType documentStoreType) { + this.documentStoreType = documentStoreType; + } + + public LocalDocumentStoreConfiguration getLocalConfiguration() { + return localConfiguration; + } + + public void setLocalConfiguration(LocalDocumentStoreConfiguration localConfiguration) { + this.localConfiguration = localConfiguration; + } + + public JcaDocumentStoreConfiguration getJcaConfiguration() { + return jcaConfiguration; + } + + public void setJcaConfiguration(JcaDocumentStoreConfiguration jcaConfiguration) { + this.jcaConfiguration = jcaConfiguration; + } + + public WebDavDocumentStoreConfiguration getWebDavConfiguration() { + return webDavConfiguration; + } + + public void setWebDavConfiguration(WebDavDocumentStoreConfiguration webDavConfiguration) { + this.webDavConfiguration = webDavConfiguration; + } + + public DBDocumentStoreConfiguration getDbConfiguration() { + return dbConfiguration; + } + + public void setDbConfiguration(DBDocumentStoreConfiguration dbDavConfiguration) { + this.dbConfiguration = dbDavConfiguration; + } + + @Override + public String toString() { + return "DocumentStoreConfiguration [documentStoreType=" + documentStoreType + ", localConfiguration=" + localConfiguration + + ", jcaConfiguration=" + jcaConfiguration + ", webDavConfiguration=" + webDavConfiguration + ", DBConfiguration=" + dbConfiguration + "]"; + } +} diff --git a/core-document-store/src/main/java/org/gluu/service/document/store/conf/DocumentStoreType.java b/core-document-store/src/main/java/org/gluu/service/document/store/conf/DocumentStoreType.java new file mode 100644 index 000000000..e941823f9 --- /dev/null +++ b/core-document-store/src/main/java/org/gluu/service/document/store/conf/DocumentStoreType.java @@ -0,0 +1,11 @@ +package org.gluu.service.document.store.conf; + +import javax.xml.bind.annotation.XmlEnum; + +/** + * @author Yuriy Movchan on 04/10/2020 + */ +@XmlEnum(String.class) +public enum DocumentStoreType { + LOCAL, JCA, WEB_DAV, DB +} diff --git a/core-document-store/src/main/java/org/gluu/service/document/store/conf/JcaDocumentStoreConfiguration.java b/core-document-store/src/main/java/org/gluu/service/document/store/conf/JcaDocumentStoreConfiguration.java new file mode 100644 index 000000000..65da3a34c --- /dev/null +++ b/core-document-store/src/main/java/org/gluu/service/document/store/conf/JcaDocumentStoreConfiguration.java @@ -0,0 +1,80 @@ +package org.gluu.service.document.store.conf; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import java.io.Serializable; + +/** + * @author Yuriy Movchan on 04/10/2020 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class JcaDocumentStoreConfiguration implements Serializable { + + private static final long serialVersionUID = 3380170170265842427L; + + private String serverUrl; // http://localhost:8080/rmi + private String workspaceName; + private int connectionTimeout; + + private String userId; + private String password; + + @JsonIgnore + private String decryptedPassword; + + public String getServerUrl() { + return serverUrl; + } + + public void setServerUrl(String serverUrl) { + this.serverUrl = serverUrl; + } + + public String getWorkspaceName() { + return workspaceName; + } + + public void setWorkspaceName(String workspaceName) { + this.workspaceName = workspaceName; + } + + public int getConnectionTimeout() { + return connectionTimeout; + } + + public void setConnectionTimeout(int connectionTimeout) { + this.connectionTimeout = connectionTimeout; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getDecryptedPassword() { + return decryptedPassword; + } + + public void setDecryptedPassword(String decryptedPassword) { + this.decryptedPassword = decryptedPassword; + } + + @Override + public String toString() { + return "JcaDocumentStoreConfiguration [serverUrl=" + serverUrl + ", workspaceName=" + workspaceName + ", connectionTimeout=" + + connectionTimeout + ", userId=" + userId + "]"; + } + +} diff --git a/core-document-store/src/main/java/org/gluu/service/document/store/conf/LocalDocumentStoreConfiguration.java b/core-document-store/src/main/java/org/gluu/service/document/store/conf/LocalDocumentStoreConfiguration.java new file mode 100644 index 000000000..1229a0d34 --- /dev/null +++ b/core-document-store/src/main/java/org/gluu/service/document/store/conf/LocalDocumentStoreConfiguration.java @@ -0,0 +1,32 @@ +package org.gluu.service.document.store.conf; + +import java.io.Serializable; + +import javax.xml.bind.annotation.XmlElement; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +/** + * @author Yuriy Movchan on 04/10/2020 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class LocalDocumentStoreConfiguration implements Serializable { + + private static final long serialVersionUID = -2403247753790576983L; + + @XmlElement(name = "baseLocation") + private String baseLocation = "/"; + + public String getBaseLocation() { + return baseLocation; + } + + public void setBaseLocation(String baseLocation) { + this.baseLocation = baseLocation; + } + + @Override + public String toString() { + return "LocalConfiguration [baseLocation=" + baseLocation + "]"; + } +} diff --git a/core-document-store/src/main/java/org/gluu/service/document/store/conf/WebDavDocumentStoreConfiguration.java b/core-document-store/src/main/java/org/gluu/service/document/store/conf/WebDavDocumentStoreConfiguration.java new file mode 100644 index 000000000..81b22fd5f --- /dev/null +++ b/core-document-store/src/main/java/org/gluu/service/document/store/conf/WebDavDocumentStoreConfiguration.java @@ -0,0 +1,77 @@ +package org.gluu.service.document.store.conf; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import java.io.Serializable; + +/** + * @author Yuriy Movchan on 04/10/2020 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class WebDavDocumentStoreConfiguration implements Serializable { + + private static final long serialVersionUID = 3380170170265842538L; + + private String serverUrl; // http://localhost:8080 + private String workspaceName; + private int connectionTimeout; + + private String userId; + private String password; + private String decryptedPassword; + + public String getServerUrl() { + return serverUrl; + } + + public void setServerUrl(String serverUrl) { + this.serverUrl = serverUrl; + } + + public String getWorkspaceName() { + return workspaceName; + } + + public void setWorkspaceName(String workspaceName) { + this.workspaceName = workspaceName; + } + + public int getConnectionTimeout() { + return connectionTimeout; + } + + public void setConnectionTimeout(int connectionTimeout) { + this.connectionTimeout = connectionTimeout; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getDecryptedPassword() { + return decryptedPassword; + } + + public void setDecryptedPassword(String decryptedPassword) { + this.decryptedPassword = decryptedPassword; + } + + @Override + public String toString() { + return "WebDavDocumentStoreConfiguration [serverUrl=" + serverUrl + ", workspaceName=" + workspaceName + ", connectionTimeout=" + + connectionTimeout + ", userId=" + userId + "]"; + } + +} diff --git a/core-document-store/src/main/java/org/gluu/service/document/store/provider/DBDocumentStoreProvider.java b/core-document-store/src/main/java/org/gluu/service/document/store/provider/DBDocumentStoreProvider.java new file mode 100644 index 000000000..ed1b8209b --- /dev/null +++ b/core-document-store/src/main/java/org/gluu/service/document/store/provider/DBDocumentStoreProvider.java @@ -0,0 +1,236 @@ +package org.gluu.service.document.store.provider; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Base64; +import java.util.List; + +import javax.annotation.PostConstruct; +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; + +import org.apache.commons.io.IOUtils; +import org.gluu.persist.PersistenceEntryManager; +import org.gluu.service.document.store.conf.DBDocumentStoreConfiguration; +import org.gluu.service.document.store.conf.DocumentStoreConfiguration; +import org.gluu.service.document.store.conf.DocumentStoreType; +import org.gluu.service.document.store.service.DBDocumentService; +import org.gluu.service.document.store.service.OxDocument; +import org.gluu.util.StringHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Shekhar L. on 26/04/2022 + */ +@ApplicationScoped +public class DBDocumentStoreProvider extends DocumentStoreProvider { + + @Inject + private Logger log; + + @Inject + private DBDocumentService documentService; + + @Inject + private DocumentStoreConfiguration documentStoreConfiguration; + + private DBDocumentStoreConfiguration dbDocumentStoreConfiguration; + + public DocumentStoreType getProviderType() { + return DocumentStoreType.DB; + } + + @PostConstruct + public void init() { + this.dbDocumentStoreConfiguration = documentStoreConfiguration.getDbConfiguration(); + } + + public void configure(DocumentStoreConfiguration documentStoreConfiguration, PersistenceEntryManager persistenceEntryManager) { + this.log = LoggerFactory.getLogger(DBDocumentStoreProvider.class); + this.documentStoreConfiguration = documentStoreConfiguration; + if(documentService == null) { + this.documentService = new DBDocumentService(persistenceEntryManager); + } + } + + @Override + public void create() { + + } + + @Override + public void destroy() { + + } + + @Override + public boolean hasDocument(String DisplayName) { + log.debug("Has document: '{}'", DisplayName); + if (StringHelper.isEmpty(DisplayName)) { + throw new IllegalArgumentException("Specified path should not be empty!"); + } + OxDocument oxDocument = null; + try { + oxDocument = documentService.getOxDocumentByDisplayName(DisplayName); + if(oxDocument != null) { + return true; + } + } catch (Exception e) { + log.error("Failed to check if path '" + DisplayName + "' exists in repository", e); + } + + return false; + } + + @Override + public boolean saveDocument(String name, String documentContent, Charset charset, List moduleList) { + log.debug("Save document: '{}'", name); + try { + boolean update = true; + OxDocument oxDocument = documentService.getOxDocumentByDisplayName(name); + if (oxDocument == null) { + update = false; + oxDocument = new OxDocument(); + oxDocument.setDisplayName(name); + oxDocument.setInum(documentService.generateInumForNewOxDocument()); + String dn = "inum=" + oxDocument.getInum() + ",ou=document,o=gluu"; + oxDocument.setDn(dn); + } + + oxDocument.setDocument(documentContent); + oxDocument.setDescription(name); + oxDocument.setOxEnabled(true); + oxDocument.setOxModuleProperty(moduleList); + + if (update) + documentService.updateOxDocument(oxDocument); + else + documentService.addOxDocument(oxDocument); + return true; + + } catch (Exception ex) { + log.error("Failed to write document to file '{}'", name, ex); + } + + return false; + } + + @Override + public boolean saveDocumentStream(String name, InputStream documentStream, List moduleList) { + try { + // log.debug("Save document from stream: '{}'", name); + boolean update = true; + OxDocument oxDocument = documentService.getOxDocumentByDisplayName(name); + if (oxDocument == null) { + update = false; + oxDocument = new OxDocument(); + oxDocument.setDisplayName(name); + + String inum = documentService.generateInumForNewOxDocument(); + oxDocument.setInum(inum); + + String dn = "inum=" + oxDocument.getInum() + ",ou=document,o=gluu"; + oxDocument.setDn(dn); + } + String documentContent = new String(documentStream.readAllBytes(), StandardCharsets.UTF_8); + oxDocument.setDocument(documentContent); + oxDocument.setDescription(name); + oxDocument.setOxEnabled(true); + oxDocument.setOxModuleProperty(moduleList); + + if(update) + documentService.updateOxDocument(oxDocument); + else + documentService.addOxDocument(oxDocument); + + return true; + } catch (IOException e) { + log.error("Failed to write document from stream to file '{}'", name, e); + } catch (Exception e) { + log.error("Failed to write document from stream to file '{}'", name, e); + } + + return false; + } + + + @Override + public String readDocument(String name, Charset charset) { + log.debug("Read document: '{}'", name); + OxDocument oxDocument; + try { + oxDocument = documentService.getOxDocumentByDisplayName(name); + if(oxDocument != null) { + return oxDocument.getDocument(); + } + } catch (Exception e) { + log.error("Failed to read document as stream from file '{}'", name, e); + } + return null; + } + + @Override + public InputStream readDocumentAsStream(String name) { + log.debug("Read document as stream: '{}'", name); + String filecontecnt = readDocument(name, null); + if (filecontecnt == null) { + log.error("Document file '{}' isn't exist", name); + return null; + } + + InputStream InputStream = new ByteArrayInputStream(filecontecnt.getBytes()); + return InputStream; + } + + @Override + public boolean renameDocument(String currentDisplayName, String destinationDisplayName) { + log.debug("Rename document: '{}' -> '{}'", currentDisplayName, destinationDisplayName); + OxDocument oxDocument; + try { + oxDocument = documentService.getOxDocumentByDisplayName(currentDisplayName); + if (oxDocument == null) { + log.error("Document doesn't Exist with the name '{}'", currentDisplayName); + return false; + } + oxDocument.setDisplayName(destinationDisplayName); + documentService.updateOxDocument(oxDocument); + OxDocument oxDocumentDestination = documentService.getOxDocumentByDisplayName(destinationDisplayName); + if(oxDocumentDestination == null) { + log.error("Failed to rename to destination file '{}'", destinationDisplayName); + return false; + } + } catch (Exception e) { + log.error("Failed to rename to destination file '{}'", destinationDisplayName); + } + return true; + } + + @Override + public boolean removeDocument(String inum) { + log.debug("Remove document: '{}'", inum); + OxDocument oxDocument; + try { + oxDocument = documentService.getOxDocumentByInum(inum); + if(oxDocument == null) { + log.error(" document not exist file '{}'", inum); + return false; + } + + documentService.removeOxDocument(oxDocument); + OxDocument checkOxDocument = documentService.getOxDocumentByInum(inum); + if(checkOxDocument == null) { + return true; + } + return false; + } catch (Exception e) { + log.error("Failed to remove document file '{}'", inum, e); + } + return false; + } + +} diff --git a/core-document-store/src/main/java/org/gluu/service/document/store/provider/DocumentStore.java b/core-document-store/src/main/java/org/gluu/service/document/store/provider/DocumentStore.java new file mode 100644 index 000000000..72cc51ddf --- /dev/null +++ b/core-document-store/src/main/java/org/gluu/service/document/store/provider/DocumentStore.java @@ -0,0 +1,52 @@ +package org.gluu.service.document.store.provider; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.Charset; +import java.util.List; + +import org.gluu.service.document.store.conf.DocumentStoreType; + +/** + * @author Yuriy Movchan on 04/10/2020 + */ +public interface DocumentStore { + + /** + * Method to check if there is key in cache + */ + boolean hasDocument(String path); + + /** + * Save document into store + */ + boolean saveDocument(String path, String documentContent, Charset charset, List moduleList); + + /** + * Save document stream into store + */ + boolean saveDocumentStream(String path, InputStream documentStream, List moduleList); + + /** + * Load document from store + */ + String readDocument(String path, Charset charset); + + /** + * Load document from store as stream + */ + public InputStream readDocumentAsStream(String path) ; + + /** + * Removes an object document from store + */ + boolean removeDocument(String path); + + /** + * Rename an object in document store + */ + boolean renameDocument(String currentPath, String destinationPath); + + public abstract DocumentStoreType getProviderType(); + +} \ No newline at end of file diff --git a/core-document-store/src/main/java/org/gluu/service/document/store/provider/DocumentStoreProvider.java b/core-document-store/src/main/java/org/gluu/service/document/store/provider/DocumentStoreProvider.java new file mode 100644 index 000000000..71364d7bf --- /dev/null +++ b/core-document-store/src/main/java/org/gluu/service/document/store/provider/DocumentStoreProvider.java @@ -0,0 +1,12 @@ +package org.gluu.service.document.store.provider; + +/** + * @author Yuriy Movchan on 04/10/2020 + */ +public abstract class DocumentStoreProvider implements DocumentStore { + + public abstract void create(); + + public abstract void destroy(); + +} diff --git a/core-document-store/src/main/java/org/gluu/service/document/store/provider/DocumentStoreProviderFactory.java b/core-document-store/src/main/java/org/gluu/service/document/store/provider/DocumentStoreProviderFactory.java new file mode 100644 index 000000000..01b9cbf9c --- /dev/null +++ b/core-document-store/src/main/java/org/gluu/service/document/store/provider/DocumentStoreProviderFactory.java @@ -0,0 +1,92 @@ +package org.gluu.service.document.store.provider; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Any; +import javax.enterprise.inject.Instance; +import javax.enterprise.inject.Produces; +import javax.inject.Inject; + +import org.gluu.service.document.store.LocalDocumentStore; +import org.gluu.service.document.store.conf.DocumentStoreConfiguration; +import org.gluu.service.document.store.conf.DocumentStoreType; +import org.slf4j.Logger; + +/** + * @author Yuriy Movchan on 04/10/2020 + */ +@ApplicationScoped +public class DocumentStoreProviderFactory { + + @Inject + private Logger log; + + @Inject + private DocumentStoreConfiguration documentStoreConfiguration; + + @Inject + @Any + private Instance instance; + + @Produces + @ApplicationScoped + public DocumentStoreProvider getDocumentStoreProvider() { + log.debug("Started to create document store provider"); + + + return getDocumentStoreProvider(documentStoreConfiguration); + } + + public DocumentStoreProvider getDocumentStoreProvider(DocumentStoreConfiguration documentStoreConfiguration) { + DocumentStoreType documentStoreType = documentStoreConfiguration.getDocumentStoreType(); + + if (documentStoreType == null) { + log.error("Failed to initialize DocumentStoreProvider, DocumentStoreProviderType is null. Fallback to LOCAL type."); + documentStoreType = DocumentStoreType.LOCAL; + } + + // Create proxied bean + DocumentStoreProvider documentStoreProvider = null; + switch (documentStoreType) { + case LOCAL: + documentStoreProvider = instance.select(LocalDocumentStoreProvider.class).get(); + break; + case JCA: + documentStoreProvider = instance.select(JcaDocumentStoreProvider.class).get(); + break; + case WEB_DAV: + documentStoreProvider = instance.select(WebDavDocumentStoreProvider.class).get(); + break; + case DB: + documentStoreProvider = instance.select(DBDocumentStoreProvider.class).get(); + break; + + } + + if (documentStoreProvider == null) { + throw new RuntimeException("Failed to initialize DocumentStoreProvider, DocumentStoreProviderType is unsupported: " + documentStoreType); + } + + documentStoreProvider.create(); + + return documentStoreProvider; + } + + @Produces + @ApplicationScoped + @LocalDocumentStore + public DocumentStoreProvider getLocalDocumentStoreProvider() { + log.debug("Started to create local document store provider"); + + DocumentStoreType documentStoreType = DocumentStoreType.LOCAL; + DocumentStoreProvider documentStoreProvider = instance.select(LocalDocumentStoreProvider.class).get(); + + if (documentStoreProvider == null) { + throw new RuntimeException("Failed to initialize DocumentStoreProvider, DocumentStoreProviderType is unsupported: " + documentStoreType); + } + + documentStoreProvider.create(); + + return documentStoreProvider; + } + +} diff --git a/core-document-store/src/main/java/org/gluu/service/document/store/provider/JcaDocumentStoreProvider.java b/core-document-store/src/main/java/org/gluu/service/document/store/provider/JcaDocumentStoreProvider.java new file mode 100644 index 000000000..30af4248a --- /dev/null +++ b/core-document-store/src/main/java/org/gluu/service/document/store/provider/JcaDocumentStoreProvider.java @@ -0,0 +1,408 @@ +package org.gluu.service.document.store.provider; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.Charset; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.FutureTask; +import java.util.concurrent.TimeUnit; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; +import javax.jcr.AccessDeniedException; +import javax.jcr.Binary; +import javax.jcr.Node; +import javax.jcr.Property; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.SimpleCredentials; +import javax.jcr.Value; +import javax.jcr.lock.LockException; +import javax.jcr.nodetype.ConstraintViolationException; +import javax.jcr.nodetype.NodeType; +import javax.jcr.version.VersionException; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.jackrabbit.JcrConstants; +import org.apache.jackrabbit.commons.JcrUtils; +import org.apache.jackrabbit.rmi.repository.URLRemoteRepository; +import org.gluu.service.document.store.conf.DocumentStoreConfiguration; +import org.gluu.service.document.store.conf.DocumentStoreType; +import org.gluu.service.document.store.conf.JcaDocumentStoreConfiguration; +import org.gluu.util.StringHelper; +import org.gluu.util.security.StringEncrypter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Yuriy Movchan on 04/10/2020 + */ +@ApplicationScoped +public class JcaDocumentStoreProvider extends DocumentStoreProvider { + + @Inject + private Logger log; + + + @Inject + private DocumentStoreConfiguration documentStoreConfiguration; + + @Inject + private StringEncrypter stringEncrypter; + + private JcaDocumentStoreConfiguration jcaDocumentStoreConfiguration; + + private URLRemoteRepository repository; + private SimpleCredentials credentials; + private String workspaceName; + private long connectionTimeout; + + public JcaDocumentStoreProvider() { + } + + @PostConstruct + public void init() { + this.jcaDocumentStoreConfiguration = documentStoreConfiguration.getJcaConfiguration(); + } + + public void create() { + try { + log.debug("Starting JcaDocumentStoreProvider ..."); + decryptPassword(jcaDocumentStoreConfiguration); + this.repository = new URLRemoteRepository(jcaDocumentStoreConfiguration.getServerUrl()); + + String password = StringUtils.isBlank(jcaDocumentStoreConfiguration.getDecryptedPassword()) ? "" : jcaDocumentStoreConfiguration.getDecryptedPassword(); + + this.credentials = new SimpleCredentials(jcaDocumentStoreConfiguration.getUserId(), + password.toCharArray()); + + this.workspaceName = jcaDocumentStoreConfiguration.getWorkspaceName(); + this.connectionTimeout = jcaDocumentStoreConfiguration.getConnectionTimeout(); + } catch (Exception ex) { + throw new IllegalStateException("Error starting JcaDocumentStoreProvider", ex); + } + } + + public void configure(DocumentStoreConfiguration documentStoreConfiguration, StringEncrypter stringEncrypter) { + this.log = LoggerFactory.getLogger(DocumentStoreConfiguration.class); + this.documentStoreConfiguration = documentStoreConfiguration; + this.stringEncrypter = stringEncrypter; + } + + @PreDestroy + public void destroy() { + log.debug("Destroying JcaDocumentStoreProvider"); + + this.repository = null; + + log.debug("Destroyed JcaDocumentStoreProvider"); + } + + public void setJcaDocumentStoreConfiguration(JcaDocumentStoreConfiguration jcaDocumentStoreConfiguration) { + this.jcaDocumentStoreConfiguration = jcaDocumentStoreConfiguration; + } + + public DocumentStoreType getProviderType() { + return DocumentStoreType.JCA; + } + + @Override + public boolean hasDocument(String path) { + log.debug("Has document: '{}'", path); + + if (StringHelper.isEmpty(path)) { + throw new IllegalArgumentException("Specified path should not be empty!"); + } + + Node fileNode = null; + Session session; + try { + session = getSessionWithTimeout(); + try { + fileNode = JcrUtils.getNodeIfExists(getNormalizedPath(path), session); + } finally { + closeSession(session); + } + } catch (RepositoryException ex) { + log.error("Failed to check if path '" + path + "' exists in repository", ex); + } + + return fileNode != null; + } + + @Override + public boolean saveDocument(String path, String documentContent, Charset charset, List moduleList) { + log.debug("Save document: '{}'", path); + + String normalizedPath = getNormalizedPath(path); + try { + Session session = getSessionWithTimeout(); + try { + Node contentNode = getOrCreateContentNode(normalizedPath, session); + Value value = session.getValueFactory().createValue(documentContent); + contentNode.setProperty("jcr:data", value); + + session.save(); + return true; + } finally { + closeSession(session); + } + } catch (RepositoryException ex) { + log.error("Failed to write document to file '{}'", path, ex); + } + + return false; + } + + @Override + public boolean saveDocumentStream(String path, InputStream documentStream, List moduleList) { + log.debug("Save document from stream: '{}'", path); + + String normalizedPath = getNormalizedPath(path); + try { + Session session = getSessionWithTimeout(); + try { + Node contentNode = getOrCreateContentNode(normalizedPath, session); + Binary value = session.getValueFactory().createBinary(documentStream); + contentNode.setProperty("jcr:data", value); + + session.save(); + return true; + } finally { + closeSession(session); + } + } catch (RepositoryException ex) { + log.error("Failed to write document from stream to file '{}'", path, ex); + } + + return false; + } + + + @Override + public String readDocument(String path, Charset charset) { + log.debug("Read document: '{}'", path); + + String normalizedPath = getNormalizedPath(path); + try { + Session session = getSessionWithTimeout(); + try { + Node fileNode = JcrUtils.getNodeIfExists(normalizedPath, session); + if (fileNode == null) { + log.error("Document file '{}' isn't exist", path); + return null; + } + + Node contentNode = fileNode.getNode(JcrConstants.JCR_CONTENT); + Property property = contentNode.getProperty("jcr:data"); + try (InputStream in = property.getBinary().getStream()) { + return IOUtils.toString(in, charset); + } + } finally { + closeSession(session); + } + } catch (IOException ex) { + } catch (RepositoryException ex) { + log.error("Failed to read document from file '{}'", path, ex); + } + + return null; + } + + @Override + public InputStream readDocumentAsStream(String path) { + log.debug("Read document as stream: '{}'", path); + + String normalizedPath = getNormalizedPath(path); + try { + Session session = getSessionWithTimeout(); + try { + Node fileNode = JcrUtils.getNodeIfExists(normalizedPath, session); + if (fileNode == null) { + log.error("Document file '{}' isn't exist", path); + return null; + } + + Node contentNode = fileNode.getNode(JcrConstants.JCR_CONTENT); + Property property = contentNode.getProperty("jcr:data"); + try (InputStream in = property.getBinary().getStream()) { + // Note: We can't return real input stream because we need to make sure that we close session + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + IOUtils.copy(in, bos); + + return new ByteArrayInputStream(bos.toByteArray()); + } + } finally { + closeSession(session); + } + } catch (IOException ex) { + } catch (RepositoryException ex) { + log.error("Failed to read document as stream from file '{}'", path, ex); + } + + return null; + } + + @Override + public boolean renameDocument(String currentPath, String destinationPath) { + log.debug("Rename document: '{}' -> '{}'", currentPath, destinationPath); + + String normalizedCurrentPath = getNormalizedPath(currentPath); + String normalizedDestinationPath = getNormalizedPath(destinationPath); + + try { + Session session = getSessionWithTimeout(); + try { + removeDocument(normalizedDestinationPath, session); + + createPath(normalizedDestinationPath, session); + session.move(normalizedCurrentPath, normalizedDestinationPath); + + session.save(); + return true; + } finally { + closeSession(session); + } + } catch (RepositoryException ex) { + log.error("Failed to rename to destination file '{}'", destinationPath, ex); + } + + return false; + } + + @Override + public boolean removeDocument(String path) { + log.debug("Remove document: '{}'", path); + + try { + Session session = getSessionWithTimeout(); + try { + removeDocument(path, session); + + session.save(); + return true; + } finally { + closeSession(session); + } + } catch (RepositoryException ex) { + log.error("Failed to remove document file '{}'", path, ex); + } + + return false; + } + + private void removeDocument(String path, Session session) + throws RepositoryException, VersionException, LockException, ConstraintViolationException, AccessDeniedException { + Node fileNode = JcrUtils.getNodeIfExists(getNormalizedPath(path), session); + if (fileNode != null) { + fileNode.remove(); + } + } + + private void decryptPassword(JcaDocumentStoreConfiguration jcaDocumentStoreConfiguration) { + try { + String encryptedPassword = jcaDocumentStoreConfiguration.getPassword(); + if (StringUtils.isNotBlank(encryptedPassword)) { + jcaDocumentStoreConfiguration.setDecryptedPassword(stringEncrypter.decrypt(encryptedPassword)); + log.trace("Decrypted JCA password successfully."); + } + } catch (StringEncrypter.EncryptionException ex) { + jcaDocumentStoreConfiguration.setDecryptedPassword(jcaDocumentStoreConfiguration.getPassword()); + log.error("Error during JCA password decryption", ex); + } + } + + private Session getSession() throws RepositoryException { + return repository.login(credentials, workspaceName); + } + + public Session getSessionWithTimeout() throws RepositoryException { + try { + CallableSession cs = new CallableSession(repository, credentials, workspaceName); + FutureTask future = new FutureTask(cs); + ExecutorService executor = Executors.newSingleThreadExecutor(); + executor.execute(future); + return future.get(connectionTimeout * 1000, TimeUnit.MILLISECONDS); + } catch (Exception ex) { + throw new RepositoryException("Failed to get session", ex); + } + } + + private void closeSession(Session session) { + if (session != null && session.isLive()) { + session.logout(); + } + } + + private String getNormalizedPath(String path) { + return path.replace("\\", "/").replace(" ", ""); + } + + private Node getOrCreateContentNode(String path, Session session) throws RepositoryException { + Node fileNode = JcrUtils.getNodeIfExists(getNormalizedPath(path), session); + Node contentNode = null; + if (fileNode == null) { + fileNode = JcrUtils.getOrCreateByPath(path, NodeType.NT_FOLDER, NodeType.NT_FILE, session, false); + contentNode = fileNode.addNode(JcrConstants.JCR_CONTENT, NodeType.NT_RESOURCE); + } else { + contentNode = fileNode.getNode(JcrConstants.JCR_CONTENT); + } + + return contentNode; + } + + private void createPath(String path, Session session) throws RepositoryException { + File filePath = new File(path); + String folderPath = filePath.getParentFile().getPath(); + + String normalizedFolderPath = getNormalizedPath(folderPath); + JcrUtils.getOrCreateByPath(normalizedFolderPath, NodeType.NT_FOLDER, session); + } + + class CallableSession implements Callable { + + private URLRemoteRepository repository; + private SimpleCredentials credentials; + private String workspaceName; + + public CallableSession(URLRemoteRepository repository, SimpleCredentials credentials, String workspaceName) { + this.repository = repository; + this.credentials = credentials; + this.workspaceName = workspaceName; + } + + @Override + public Session call() throws Exception { + return repository.login(credentials, workspaceName); + } + } + + public boolean isConnected() { + log.debug("Check if server available"); + + Node fileNode = null; + Session session; + try { + session = getSessionWithTimeout(); + try { + fileNode = JcrUtils.getNodeIfExists(getNormalizedPath("/"), session); + } finally { + closeSession(session); + } + } catch (RepositoryException ex) { + log.error("Failed to check if server available", ex); + } + + return fileNode != null; + } + +} diff --git a/core-document-store/src/main/java/org/gluu/service/document/store/provider/LocalDocumentStoreProvider.java b/core-document-store/src/main/java/org/gluu/service/document/store/provider/LocalDocumentStoreProvider.java new file mode 100644 index 000000000..0ee4e4b40 --- /dev/null +++ b/core-document-store/src/main/java/org/gluu/service/document/store/provider/LocalDocumentStoreProvider.java @@ -0,0 +1,224 @@ +package org.gluu.service.document.store.provider; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.Charset; +import java.util.List; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.gluu.service.document.store.conf.DocumentStoreConfiguration; +import org.gluu.service.document.store.conf.DocumentStoreType; +import org.gluu.service.document.store.conf.LocalDocumentStoreConfiguration; +import org.gluu.util.StringHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Yuriy Movchan on 04/10/2020 + */ +@ApplicationScoped +public class LocalDocumentStoreProvider extends DocumentStoreProvider { + + @Inject + private Logger log; + + @Inject + private DocumentStoreConfiguration documentStoreConfiguration; + + private LocalDocumentStoreConfiguration localDocumentStoreConfiguration; + + private String baseLocation; + + public LocalDocumentStoreProvider() { + } + + @PostConstruct + public void init() { + this.localDocumentStoreConfiguration = documentStoreConfiguration.getLocalConfiguration(); + } + + @Override + public void create() { + log.debug("Starting LocalDocumentStoreProvider ..."); + + if (StringHelper.isEmpty(localDocumentStoreConfiguration.getBaseLocation())) { + String osName = System.getProperty("os.name"); + if (StringHelper.isNotEmpty(osName) && osName.toLowerCase().startsWith("windows")) { + baseLocation = ""; + return; + } + throw new IllegalArgumentException("Base location should not be empty"); + } + + baseLocation = new File(localDocumentStoreConfiguration.getBaseLocation()).getAbsolutePath(); + } + + public void configure(DocumentStoreConfiguration documentStoreConfiguration) { + this.log = LoggerFactory.getLogger(DocumentStoreConfiguration.class); + this.documentStoreConfiguration = documentStoreConfiguration; + } + + @PreDestroy + @Override + public void destroy() { + log.debug("Destroying LocalDocumentStoreProvider"); + + log.debug("Destroyed LocalDocumentStoreProvider"); + } + + @Override + public DocumentStoreType getProviderType() { + return DocumentStoreType.LOCAL; + } + + @Override + public boolean hasDocument(String path) { + log.debug("Has document: '{}'", path); + + if (StringHelper.isEmpty(path)) { + throw new IllegalArgumentException("Specified path should not be empty!"); + } + + File file = buildFilePath(path); + + return file.exists(); + } + + @Override + public boolean saveDocument(String path, String documentContent, Charset charset, List moduleList) { + log.debug("Save document: '{}'", path); + + File file = buildFilePath(path); + if (!createParentPath(file)) { + return false; + } + + try (FileOutputStream os = FileUtils.openOutputStream(file)) { + IOUtils.write(documentContent, os, charset); + os.flush(); + + return true; + } catch (IOException ex) { + log.error("Failed to write document to file '{}'", file.getAbsolutePath(), ex); + } + + return false; + } + + @Override + public boolean saveDocumentStream(String path, InputStream documentStream, List moduleList) { + log.debug("Save document from stream: '{}'", path); + + File file = buildFilePath(path); + if (!createParentPath(file)) { + return false; + } + + try (FileOutputStream os = FileUtils.openOutputStream(file)) { + IOUtils.copy(documentStream, os); + os.flush(); + + return true; + } catch (IOException ex) { + log.error("Failed to write document from stream to file '{}'", file.getAbsolutePath(), ex); + } + + return false; + } + + @Override + public String readDocument(String path, Charset charset) { + log.debug("Read document: '{}'", path); + + File file = buildFilePath(path); + if (!createParentPath(file)) { + return null; + } + + try { + return FileUtils.readFileToString(file, charset); + } catch (IOException ex) { + log.error("Failed to read document from file '{}'", file.getAbsolutePath(), ex); + } + + return null; + } + + @Override + public InputStream readDocumentAsStream(String path) { + log.debug("Read document as stream: '{}'", path); + + File file = buildFilePath(path); + + try { + return new BufferedInputStream(FileUtils.openInputStream(file)); + } catch (IOException ex) { + log.error("Failed to read document as stream from file '{}'", file.getAbsolutePath(), ex); + } + + return null; + } + + @Override + public boolean renameDocument(String currentPath, String destinationPath) { + log.debug("Rename document: '{}' -> '{}'", currentPath, destinationPath); + + File currentFile = buildFilePath(currentPath); + File destinationFile = buildFilePath(destinationPath); + + if (!removeDocument(destinationPath)) { + log.error("Failed to remove destination file '{}'", destinationFile.getAbsolutePath()); + } + + try { + currentFile.renameTo(destinationFile); + return true; + } catch (Exception ex) { + log.error("Failed to rename to destination file '{}'", destinationFile.getAbsolutePath(), ex); + } + + return false; + } + + @Override + public boolean removeDocument(String path) { + log.debug("Remove document: '{}'", path); + + if (!hasDocument(path)) { + return true; + } + + File file = buildFilePath(path); + if (!createParentPath(file)) { + return false; + } + + return FileUtils.deleteQuietly(file); + } + + private boolean createParentPath(File file) { + try { + FileUtils.forceMkdirParent(file); + return true; + } catch (IOException ex) { + log.error("Failed to create path to file '{}'", file.getAbsolutePath(), ex); + } + + return false; + } + + private File buildFilePath(String path) { + String filePath = baseLocation + File.separator + path; + return new File(filePath); + } + +} diff --git a/core-document-store/src/main/java/org/gluu/service/document/store/provider/WebDavDocumentStoreProvider.java b/core-document-store/src/main/java/org/gluu/service/document/store/provider/WebDavDocumentStoreProvider.java new file mode 100644 index 000000000..c09c079af --- /dev/null +++ b/core-document-store/src/main/java/org/gluu/service/document/store/provider/WebDavDocumentStoreProvider.java @@ -0,0 +1,302 @@ +package org.gluu.service.document.store.provider; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.Charset; +import java.util.List; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; +import javax.jcr.RepositoryException; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.http.HttpEntity; +import org.apache.http.HttpHost; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.AuthSchemes; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.client.protocol.HttpClientContext; +import org.apache.http.conn.SchemePortResolver; +import org.apache.http.conn.UnsupportedSchemeException; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.InputStreamEntity; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.BasicCredentialsProvider; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.DefaultHttpRequestRetryHandler; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.DefaultSchemePortResolver; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.protocol.BasicHttpContext; +import org.apache.http.protocol.HttpContext; +import org.apache.http.util.Args; +import org.apache.jackrabbit.webdav.client.methods.HttpMkcol; +import org.gluu.service.document.store.conf.DocumentStoreConfiguration; +import org.gluu.service.document.store.conf.DocumentStoreType; +import org.gluu.service.document.store.conf.WebDavDocumentStoreConfiguration; +import org.gluu.util.security.StringEncrypter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.sardine.Sardine; +import com.github.sardine.SardineFactory; + +/** + * @author Yuriy Movchan on 04/10/2020 + */ +@ApplicationScoped +public class WebDavDocumentStoreProvider extends DocumentStoreProvider { + + @Inject + private Logger log; + + @Inject + private DocumentStoreConfiguration documentStoreConfiguration; + + @Inject + private StringEncrypter stringEncrypter; + + /** + * Local context with authentication cache. Make sure the same context is used to execute + * logically related requests. + */ + protected HttpClientContext context = HttpClientContext.create(); + + private WebDavDocumentStoreConfiguration webDavDocumentStoreConfiguration; + + private Sardine client; + private HttpClient httpClient; + private String baseServerUrl; + private int connectionTimeout; + + public WebDavDocumentStoreProvider() { + } + + @PostConstruct + public void init() { + this.webDavDocumentStoreConfiguration = documentStoreConfiguration.getWebDavConfiguration(); + } + + public void create() { + try { + log.debug("Starting WebDavDocumentStoreProvider ..."); + decryptPassword(webDavDocumentStoreConfiguration); + + String password = StringUtils.isBlank(webDavDocumentStoreConfiguration.getDecryptedPassword()) ? "" : webDavDocumentStoreConfiguration.getDecryptedPassword(); + + UsernamePasswordCredentials credentials = new UsernamePasswordCredentials( + webDavDocumentStoreConfiguration.getUserId(), password); + + this.connectionTimeout = webDavDocumentStoreConfiguration.getConnectionTimeout(); + + this.httpClient = createHttpClient(credentials, connectionTimeout * 1000); + + this.baseServerUrl = webDavDocumentStoreConfiguration.getServerUrl() + "/" + + webDavDocumentStoreConfiguration.getWorkspaceName(); +/* + * Sardine +*/ + + this.client = SardineFactory.begin(webDavDocumentStoreConfiguration.getUserId(), password); + } catch (Exception ex) { + throw new IllegalStateException("Error starting JcaDocumentStoreProvider", ex); + } + } + + public void configure(DocumentStoreConfiguration documentStoreConfiguration, StringEncrypter stringEncrypter) { + this.log = LoggerFactory.getLogger(WebDavDocumentStoreProvider.class); + this.documentStoreConfiguration = documentStoreConfiguration; + this.stringEncrypter = stringEncrypter; + } + + @PreDestroy + public void destroy() { + log.debug("Destroying WebDavDocumentStoreProvider"); + + this.client = null; + + log.debug("Destroyed WebDavDocumentStoreProvider"); + } + + @Override + public DocumentStoreType getProviderType() { + return DocumentStoreType.WEB_DAV; + } + + @Override + public boolean hasDocument(String path) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean saveDocument(String path, String documentContent, Charset charset, List moduleList) { + if (true) { + log.debug("Save document: '{}'", path); + + String normalizedPath = getNormalizedPath(path); + try { + HttpPut method = new HttpPut(baseServerUrl + "/" + normalizedPath); + HttpEntity entity = new StringEntity(documentContent, charset); + method.setEntity(entity); + + HttpContext requestLocalContext = new BasicHttpContext(context); + HttpResponse response = httpClient.execute(method, requestLocalContext); + + int statusCode = response.getStatusLine().getStatusCode(); + return statusCode == HttpStatus.SC_CREATED || statusCode == HttpStatus.SC_NO_CONTENT; + } catch (IOException ex) { + log.error("Failed to write document to file '{}'", path, ex); + } + + return false; + } else { + + log.debug("Save document: '{}'", path); + + String normalizedPath = getNormalizedPath(path); + try { + String url = baseServerUrl + "/" + normalizedPath; + client.put(url, IOUtils.toInputStream(documentContent)); + + return true; + } catch (IOException ex) { + log.error("Failed to write document to file '{}'", path, ex); + } + + return false; + } + } + + @Override + public boolean saveDocumentStream(String path, InputStream documentStream, List moduleList) { + log.debug("Save document from stream: '{}'", path); + String normalizedPath = getNormalizedPath(path); + try { + HttpPut method = new HttpPut(baseServerUrl + "/" + normalizedPath); + HttpEntity entity = new InputStreamEntity(documentStream); + method.setEntity(entity); + + HttpContext requestLocalContext = new BasicHttpContext(context); + HttpResponse response = httpClient.execute(method, requestLocalContext); + + return response.getStatusLine().getStatusCode() == HttpStatus.SC_CREATED; + } catch (IOException ex) { + log.error("Failed to write document from stream to file '{}'", path, ex); + } + + return false; + } + + @Override + public String readDocument(String path, Charset charset) { + // TODO Auto-generated method stub + return null; + } + + @Override + public InputStream readDocumentAsStream(String path) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean renameDocument(String currentPath, String destinationPath) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean removeDocument(String path) { + // TODO Auto-generated method stub + return false; + } + + private void createPath(String path) throws RepositoryException { +/* + HttpMkcol mkcol = new HttpMkcol(""); + this.client.executeMethod(mkcol, ) + + File filePath = new File(path); + String folderPath = filePath.getParentFile().getPath(); + + String normalizedFolderPath = getNormalizedPath(folderPath); + JcrUtils.getOrCreateByPath(normalizedFolderPath, NodeType.NT_FOLDER, session); +*/ + } + private HttpClient createHttpClient(UsernamePasswordCredentials credentials, int timeoutInMillis) { + CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); +// credentialsProvider.setCredentials(AuthScope.ANY, credentials); + credentialsProvider.setCredentials( + new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM, AuthSchemes.BASIC), + credentials); + + SchemePortResolver portResolver = new DefaultSchemePortResolver() { + @Override + public int resolve(final HttpHost host) throws UnsupportedSchemeException { + Args.notNull(host, "HTTP host"); + final int port = host.getPort(); + if (port > 0) { + return port; + } + final String name = host.getSchemeName(); + if (name.equalsIgnoreCase("http")) { + return 8080; + } else if (name.equalsIgnoreCase("https")) { + return 8443; + } + + return super.resolve(host); + } + }; + + PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); + CloseableHttpClient httpClient = HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD) + .setSocketTimeout(timeoutInMillis).setExpectContinueEnabled(false).build()) + .setDefaultCredentialsProvider(credentialsProvider) + .setConnectionManager(cm) +/* .setRetryHandler(new DefaultHttpRequestRetryHandler(0, false))*/ +/* .setSchemePortResolver(portResolver)*/ + + .build(); + cm.setMaxTotal(50); // Increase max total connection to 50 + cm.setDefaultMaxPerRoute(10); // Increase default max connection per route to 10 + + context.setCredentialsProvider(credentialsProvider); + + return httpClient; + } + + private void decryptPassword(WebDavDocumentStoreConfiguration webDocumentStoreConfiguration) { + try { + String encryptedPassword = webDocumentStoreConfiguration.getPassword(); + if (StringUtils.isNotBlank(encryptedPassword)) { + webDocumentStoreConfiguration.setDecryptedPassword(stringEncrypter.decrypt(encryptedPassword)); + log.trace("Decrypted WebDAV password successfully."); + } + } catch (StringEncrypter.EncryptionException ex) { + log.error("Error during WebDAV password decryption", ex); + } + } + + private String getNormalizedPath(String path) { + String resultPath = path.replace("\\", "/").replace(" ", ""); + if (resultPath.startsWith("/")) { + resultPath = resultPath.substring(1); + } + + return resultPath; + } + +} diff --git a/core-document-store/src/main/java/org/gluu/service/document/store/service/BaseDocumentStoreService.java b/core-document-store/src/main/java/org/gluu/service/document/store/service/BaseDocumentStoreService.java new file mode 100644 index 000000000..def1d0b59 --- /dev/null +++ b/core-document-store/src/main/java/org/gluu/service/document/store/service/BaseDocumentStoreService.java @@ -0,0 +1,86 @@ +/* + * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2014, Gluu + */ +package org.gluu.service.document.store.service; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.Charset; +import java.util.List; + +import javax.inject.Inject; + +import org.gluu.service.document.store.conf.DocumentStoreType; +import org.gluu.service.document.store.provider.DocumentStore; +import org.gluu.service.document.store.provider.DocumentStoreProvider; +import org.slf4j.Logger; + +/** + * @author Yuriy Movchan on 04/10/2020 + */ +@SuppressWarnings("rawtypes") +public abstract class BaseDocumentStoreService implements DocumentStore { + + @Inject + private Logger log; + + public boolean hasDocument(String path) { + DocumentStoreProvider documentStoreProvider = getDocumentStoreProvider(); + + return documentStoreProvider.hasDocument(path); + } + + @Override + public boolean saveDocument(String path, String documentContent, Charset charset, List moduleList) { + DocumentStoreProvider documentStoreProvider = getDocumentStoreProvider(); + + return documentStoreProvider.saveDocument(path, documentContent, charset, moduleList); + } + + @Override + public boolean saveDocumentStream(String path, InputStream documentStream, List moduleList) { + DocumentStoreProvider documentStoreProvider = getDocumentStoreProvider(); + + return documentStoreProvider.saveDocumentStream(path, documentStream, moduleList); + } + + @Override + public String readDocument(String path, Charset charset) { + DocumentStoreProvider documentStoreProvider = getDocumentStoreProvider(); + + return documentStoreProvider.readDocument(path, charset); + } + + @Override + public InputStream readDocumentAsStream(String path) { + DocumentStoreProvider documentStoreProvider = getDocumentStoreProvider(); + + return documentStoreProvider.readDocumentAsStream(path); + } + + @Override + public boolean renameDocument(String currentPath, String destinationPath) { + DocumentStoreProvider documentStoreProvider = getDocumentStoreProvider(); + + return documentStoreProvider.renameDocument(currentPath, destinationPath); + } + + @Override + public boolean removeDocument(String path) { + DocumentStoreProvider documentStoreProvider = getDocumentStoreProvider(); + + return documentStoreProvider.removeDocument(path); + } + + @Override + public DocumentStoreType getProviderType() { + DocumentStoreProvider documentStoreProvider = getDocumentStoreProvider(); + + return documentStoreProvider.getProviderType(); + } + + protected abstract DocumentStoreProvider getDocumentStoreProvider(); + +} diff --git a/core-document-store/src/main/java/org/gluu/service/document/store/service/DBDocumentService.java b/core-document-store/src/main/java/org/gluu/service/document/store/service/DBDocumentService.java new file mode 100644 index 000000000..b2713e422 --- /dev/null +++ b/core-document-store/src/main/java/org/gluu/service/document/store/service/DBDocumentService.java @@ -0,0 +1,219 @@ +/* + * oxTrust is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2014, Gluu + */ + +package org.gluu.service.document.store.service; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.UUID; + +import javax.annotation.PostConstruct; +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Instance; +import javax.inject.Inject; +import javax.inject.Named; + +import org.gluu.persist.PersistenceEntryManager; +import org.gluu.search.filter.Filter; +import org.gluu.util.StringHelper; +import org.slf4j.Logger; + +/** + * Provides operations with OxDocument + * + * @author Shekhar L. Date : 04 April 2022 + */ +@ApplicationScoped +@Named("DBDocumentService") +public class DBDocumentService implements Serializable { + + private static final long serialVersionUID = 65734145678106186L; + + @Inject + private Logger logger; + + @Inject + private Instance persistenceEntryManagerInstance; + + private PersistenceEntryManager persistenceEntryManager; + + public DBDocumentService() {} + + public DBDocumentService(PersistenceEntryManager persistenceEntryManager) { + this.persistenceEntryManager = persistenceEntryManager; + } + + public static final String inum = "inum"; + public static final String displayName = "displayName"; + public static final String description = "description"; + + @PostConstruct + public void init() { + if (persistenceEntryManagerInstance.isResolvable()) { + this.persistenceEntryManager = persistenceEntryManagerInstance.get(); + } else { + this.persistenceEntryManager = null; + } + } + + /** + * Add new OxDocument entry + * + * @param OxDocument + * OxDocument + */ + public void addOxDocument(OxDocument oxDocument) throws Exception { + oxDocument.setCreationDate(new Date()); + persistenceEntryManager.persist(oxDocument); + } + + /** + * Remove OxDocument entry + * + * @param OxDocument + * OxDocument + */ + public void removeOxDocument(OxDocument oxDocument) throws Exception { + + persistenceEntryManager.remove(oxDocument); + } + + /** + * Get OxDocument by inum + * + * @param inum + * OxDocument Inum + * @return OxDocument + */ + public OxDocument getOxDocumentByInum(String inum) throws Exception { + OxDocument result = null; + try { + result = persistenceEntryManager.find(OxDocument.class, getDnForOxDocument(inum)); + } catch (Exception e) { + logger.error("Not able to find the oxDocument. Here is the exception message ", e); + } + return result; + } + + /** + * Build DN string for OxDocument + * + * @param inum + * OxDocument Inum + * @return DN string for specified scope or DN for OxDocument branch if inum is null + * @throws Exception + */ + public String getDnForOxDocument(String inum) throws Exception { + if (StringHelper.isEmpty(inum)) { + return String.format("ou=document,%s", "o=gluu"); + } + return String.format("inum=%s,ou=document,%s", inum, "o=gluu"); + } + + /** + * Update OxDocument entry + * + * @param OxDocument + * OxDocument + */ + public void updateOxDocument(OxDocument oxDocument) throws Exception { + persistenceEntryManager.merge(oxDocument); + } + + /** + * Generate new inum for OxDocument + * + * @return New inum for OxDocument + */ + public String generateInumForNewOxDocument() throws Exception { + OxDocument oxDocument = new OxDocument(); + String newInum = null; + String newDn = null; + newInum = generateInumForNewOxDocumentImpl(); + newDn = getDnForOxDocument(newInum); + oxDocument.setDn(newDn); + return newInum; + } + + /** + * Search scopes by pattern + * + * @param pattern + * Pattern + * @param sizeLimit + * Maximum count of results + * @return List of OxDocument + * @throws Exception + */ + public List searchOxDocuments(String pattern, int sizeLimit) { + Filter searchFilter = null; + if (StringHelper.isNotEmpty(pattern)) { + String[] targetArray = new String[] { pattern }; + Filter displayNameFilter = Filter.createSubstringFilter(displayName, null, targetArray, + null); + Filter descriptionFilter = Filter.createSubstringFilter(description, null, targetArray, + null); + searchFilter = Filter.createORFilter(displayNameFilter, descriptionFilter); + } + List result = new ArrayList<>(); + try { + result = persistenceEntryManager.findEntries(getDnForOxDocument(null), OxDocument.class, searchFilter, sizeLimit); + return result; + } catch (Exception e) { + logger.error("Failed to find OxDocument : ", e); + } + return result; + } + + /** + * Generate new inum for oxDocument + * + * @return New inum for oxDocument + * @throws Exception + */ + private String generateInumForNewOxDocumentImpl() throws Exception { + return UUID.randomUUID().toString(); + } + + public List getAllOxDocumentsList(int size) { + try { + List oxDocuments = persistenceEntryManager.findEntries(getDnForOxDocument(null), OxDocument.class, null, size); + return oxDocuments; + } catch (Exception e) { + logger.error("Failed to find OxDocument: ", e); + return new ArrayList<>(); + } + } + + /** + * returns oxDocuments by Dn + * + * @return oxDocuments + */ + + public OxDocument getOxDocumentByDn(String Dn) throws Exception { + return persistenceEntryManager.find(OxDocument.class, Dn); + } + + /** + * Get oxDocuments by DisplayName + * + * @param DisplayName + * @return oxDocuments + */ + public OxDocument getOxDocumentByDisplayName(String DisplayName) throws Exception { + OxDocument oxDocument = new OxDocument(); + oxDocument.setDisplayName(DisplayName); + oxDocument.setDn(getDnForOxDocument(null));; + List oxDocuments = persistenceEntryManager.findEntries(oxDocument); + if ((oxDocuments != null) && (oxDocuments.size() > 0)) { + return oxDocuments.get(0); + } + return null; + } +} diff --git a/core-document-store/src/main/java/org/gluu/service/document/store/service/DocumentStoreService.java b/core-document-store/src/main/java/org/gluu/service/document/store/service/DocumentStoreService.java new file mode 100644 index 000000000..fc5574f0c --- /dev/null +++ b/core-document-store/src/main/java/org/gluu/service/document/store/service/DocumentStoreService.java @@ -0,0 +1,27 @@ +/* + * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2014, Gluu + */ +package org.gluu.service.document.store.service; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; + +import org.gluu.service.document.store.provider.DocumentStoreProvider; + +/** + * @author Yuriy Movchan on 04/10/2020 + */ +@ApplicationScoped +public class DocumentStoreService extends BaseDocumentStoreService { + + @Inject + private DocumentStoreProvider documentStoreProvider; + + @Override + protected DocumentStoreProvider getDocumentStoreProvider() { + return documentStoreProvider; + } + +} diff --git a/core-document-store/src/main/java/org/gluu/service/document/store/service/LocalDocumentStoreService.java b/core-document-store/src/main/java/org/gluu/service/document/store/service/LocalDocumentStoreService.java new file mode 100644 index 000000000..2ed054149 --- /dev/null +++ b/core-document-store/src/main/java/org/gluu/service/document/store/service/LocalDocumentStoreService.java @@ -0,0 +1,30 @@ +/* + * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2014, Gluu + */ +package org.gluu.service.document.store.service; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; + +import org.gluu.service.document.store.LocalDocumentStore; +import org.gluu.service.document.store.provider.DocumentStoreProvider; + +/** + * @author Yuriy Movchan on 04/10/2020 + */ +@ApplicationScoped +public class LocalDocumentStoreService extends BaseDocumentStoreService { + + @Inject + @LocalDocumentStore + private DocumentStoreProvider documentStoreProvider; + + @Override + protected DocumentStoreProvider getDocumentStoreProvider() { + return documentStoreProvider; + } + + +} diff --git a/core-document-store/src/main/java/org/gluu/service/document/store/service/OxDocument.java b/core-document-store/src/main/java/org/gluu/service/document/store/service/OxDocument.java new file mode 100644 index 000000000..f78c96629 --- /dev/null +++ b/core-document-store/src/main/java/org/gluu/service/document/store/service/OxDocument.java @@ -0,0 +1,154 @@ +/* + * oxTrust is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2014, Gluu + */ + +package org.gluu.service.document.store.service; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +import org.gluu.persist.model.base.Entry; +import org.gluu.persist.annotation.AttributeName; +import org.gluu.persist.annotation.DataEntry; +import org.gluu.persist.annotation.ObjectClass; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; + +/** + * Group + * + * @author Yuriy Movchan Date: 11.02.2010 + */ +@DataEntry(sortBy = { "displayName" }) +@ObjectClass(value = "oxDocument") +@JsonInclude(Include.NON_NULL) +public class OxDocument extends Entry implements Serializable { + + private static final long serialVersionUID = -2812480357430436503L; + + private transient boolean selected; +//inum $ displayName $ description $ document $ oxModuleProperty $ oxLevel $ oxRevision $ oxEnabled $ oxAlias ) + @AttributeName(ignoreDuringUpdate = true) + private String inum; + + + @AttributeName + private String displayName; + + @AttributeName + private String description; + + @AttributeName + private String document; + + @AttributeName + private Date creationDate; + + @AttributeName + private List oxModuleProperty; + + @AttributeName + private String oxLevel; + + @AttributeName + private String oxRevision; + + @AttributeName + private Boolean oxEnabled; + + @AttributeName + private String oxAlias; + + public String getInum() { + return inum; + } + + public void setInum(String inum) { + this.inum = inum; + } + + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public boolean isSelected() { + return selected; + } + + public void setSelected(boolean selected) { + this.selected = selected; + } + + public String getDocument() { + return document; + } + + public void setDocument(String document) { + this.document = document; + } + + public List getOxModuleProperty() { + return oxModuleProperty; + } + + public void setOxModuleProperty(List oxModuleProperty) { + this.oxModuleProperty = oxModuleProperty; + } + + public String getOxLevel() { + return oxLevel; + } + + public void setOxLevel(String oxLevel) { + this.oxLevel = oxLevel; + } + + public String getOxRevision() { + return oxRevision; + } + + public void setOxRevision(String oxRevision) { + this.oxRevision = oxRevision; + } + + public Boolean getOxEnabled() { + return oxEnabled; + } + + public void setOxEnabled(Boolean oxEnabled) { + this.oxEnabled = oxEnabled; + } + + public String getOxAlias() { + return oxAlias; + } + + public void setOxAlias(String oxAlias) { + this.oxAlias = oxAlias; + } + + public Date getCreationDate() { + return creationDate; + } + + public void setCreationDate(Date creationDate) { + this.creationDate = creationDate; + } + +} diff --git a/persistence-hybrid/src/main/resources/META-INF/beans.xml b/core-document-store/src/main/resources/META-INF/beans.xml similarity index 100% rename from persistence-hybrid/src/main/resources/META-INF/beans.xml rename to core-document-store/src/main/resources/META-INF/beans.xml diff --git a/core-document-store/src/test/java/org/gluu/service/document/store/manual/JcaDocumentStoreManualTest.java b/core-document-store/src/test/java/org/gluu/service/document/store/manual/JcaDocumentStoreManualTest.java new file mode 100644 index 000000000..61d1a84a4 --- /dev/null +++ b/core-document-store/src/test/java/org/gluu/service/document/store/manual/JcaDocumentStoreManualTest.java @@ -0,0 +1,97 @@ +package org.gluu.service.document.store.manual; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.List; + +import javax.jcr.RepositoryException; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.gluu.service.document.store.StandaloneDocumentStoreProviderFactory; +import org.gluu.service.document.store.conf.DocumentStoreConfiguration; +import org.gluu.service.document.store.conf.DocumentStoreType; +import org.gluu.service.document.store.conf.JcaDocumentStoreConfiguration; +import org.gluu.service.document.store.conf.LocalDocumentStoreConfiguration; +import org.gluu.service.document.store.provider.DocumentStoreProvider; +import org.gluu.util.security.StringEncrypter; +import org.gluu.util.security.StringEncrypter.EncryptionException; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class JcaDocumentStoreManualTest { + + public JcaDocumentStoreManualTest() { + + } + + public static void main(String[] args) throws RepositoryException, IOException, EncryptionException { + StringEncrypter se = new StringEncrypter(StringEncrypter.DESEDE_ENCRYPTION_SCHEME, "Zqvw62DEFdhxoL4csi9hpVI4"); + DocumentStoreConfiguration dsc = new DocumentStoreConfiguration(); + dsc.setDocumentStoreType(DocumentStoreType.JCA); + + JcaDocumentStoreConfiguration jca = new JcaDocumentStoreConfiguration(); + jca.setServerUrl("http://localhost:8080/rmi"); + jca.setWorkspaceName("default"); + jca.setUserId("admin"); + jca.setPassword(se.encrypt("admin")); + jca.setConnectionTimeout(15); + + dsc.setJcaConfiguration(jca); + + LocalDocumentStoreConfiguration lca = new LocalDocumentStoreConfiguration(); + + dsc.setLocalConfiguration(lca); + + ObjectMapper om = new ObjectMapper(); + System.out.println(om.writeValueAsString(dsc)); + + StandaloneDocumentStoreProviderFactory pf = new StandaloneDocumentStoreProviderFactory(se); + DocumentStoreProvider dsp = pf.getDocumentStoreProvider(dsc); + + String doc1 = FileUtils.readFileToString(new File("V:/authorization_code.jmx"), "UTF-8"); + byte[] doc2 = FileUtils.readFileToByteArray(new File("V:/scim_requests.zip")); + + System.out.print("Has document: " + "/test2/test2/test.jmx: "); + System.out.println(dsp.hasDocument("/test2/test2/test.jmx")); + + System.out.print("Has document: " + "/test2/test3/test3.jmx: "); + System.out.println(dsp.hasDocument("/test2/test3/test3.jmx")); + + System.out.print("Write document: " + "/test2/test3/test4/test5.jmx: "); + System.out.println(dsp.saveDocumentStream("/test2/test3/test4/test5.jmx", new ByteArrayInputStream(doc2), List.of("oxtrust-server","Shibboleth"))); + + System.out.print("Has document: " + "/test2/test3/test4/test5.jmx: "); + System.out.println(dsp.hasDocument("/test2/test3/test4/test5.jmx")); + + System.out.print("Write document: " + "/test2/test3/test4/test5.jmx: "); + System.out.println(dsp.saveDocument("/test2/test3/test4/test5.jmx", doc1, StandardCharsets.UTF_8, List.of("oxtrust-server","Shibboleth"))); + + System.out.print("Has document: " + "/test2/test3/test4/test5.jmx: "); + System.out.println(dsp.hasDocument("/test2/test3/test4/test5.jmx")); + + System.out.print("Read document: " + "/test2/test3/test4/test5.jmx: "); + System.out.println(dsp.readDocument("/test2/test3/test4/test5.jmx", StandardCharsets.UTF_8)); + + System.out.print("Read document: " + "/test2/test3/test4/test5.jmx: "); + System.out.println(IOUtils.toString(dsp.readDocumentAsStream("/test2/test3/test4/test5.jmx"), StandardCharsets.UTF_8)); + + System.out.print("Rename document: " + "/test2/test3/test4/test5.jmx: "); + System.out.println(dsp.renameDocument("/test2/test3/test4/test5.jmx", "/test2/test4/test5.jmx")); + + System.out.print("Has document: " + "/test2/test3/test4/test5.jmx: "); + System.out.println(dsp.hasDocument("/test2/test3/test4/test5.jmx")); + + System.out.print("Has document: " + "/test2/test4/test5.jmx: "); + System.out.println(dsp.hasDocument("/test2/test4/test5.jmx")); + + System.out.print("Remove document: " + "test2/test4/test5.jmx: "); + System.out.println(dsp.removeDocument("/test2/test4/test5.jmx")); + + System.out.print("Has document: " + "/test2/test4/test5.jmx: "); + System.out.println(dsp.hasDocument("/test2/test4/test5.jmx")); + } + +} diff --git a/core-document-store/src/test/java/org/gluu/service/document/store/manual/WebDavDocumentStoreManualTest.java b/core-document-store/src/test/java/org/gluu/service/document/store/manual/WebDavDocumentStoreManualTest.java new file mode 100644 index 000000000..7692c60ba --- /dev/null +++ b/core-document-store/src/test/java/org/gluu/service/document/store/manual/WebDavDocumentStoreManualTest.java @@ -0,0 +1,98 @@ +package org.gluu.service.document.store.manual; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.List; + +import javax.jcr.RepositoryException; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.gluu.service.document.store.StandaloneDocumentStoreProviderFactory; +import org.gluu.service.document.store.conf.DocumentStoreConfiguration; +import org.gluu.service.document.store.conf.DocumentStoreType; +import org.gluu.service.document.store.conf.WebDavDocumentStoreConfiguration; +import org.gluu.service.document.store.conf.LocalDocumentStoreConfiguration; +import org.gluu.service.document.store.provider.DocumentStoreProvider; +import org.gluu.util.security.StringEncrypter; +import org.gluu.util.security.StringEncrypter.EncryptionException; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class WebDavDocumentStoreManualTest { + + public WebDavDocumentStoreManualTest() { + + } + + public static void main(String[] args) throws RepositoryException, IOException, EncryptionException { + StringEncrypter se = new StringEncrypter(StringEncrypter.DESEDE_ENCRYPTION_SCHEME, "Zqvw62DEFdhxoL4csi9hpVI4"); + DocumentStoreConfiguration dsc = new DocumentStoreConfiguration(); + dsc.setDocumentStoreType(DocumentStoreType.WEB_DAV); + + WebDavDocumentStoreConfiguration jca = new WebDavDocumentStoreConfiguration(); + jca.setServerUrl("http://localhost:8080/repository"); + jca.setWorkspaceName("default"); + jca.setUserId("admin"); + jca.setPassword(se.encrypt("admin")); + jca.setConnectionTimeout(15); + + dsc.setWebDavConfiguration(jca); + + LocalDocumentStoreConfiguration lca = new LocalDocumentStoreConfiguration(); + + dsc.setLocalConfiguration(lca); + + ObjectMapper om = new ObjectMapper(); + System.out.println(om.writeValueAsString(dsc)); + + StandaloneDocumentStoreProviderFactory pf = new StandaloneDocumentStoreProviderFactory(se); + DocumentStoreProvider dsp = pf.getDocumentStoreProvider(dsc); + + String doc1 = FileUtils.readFileToString(new File("V:/test.log"), "UTF-8"); + byte[] doc2 = FileUtils.readFileToByteArray(new File("V:/test.zip")); +/* + System.out.print("Has document: " + "/test2/test2/test.jmx: "); + System.out.println(dsp.hasDocument("/test2/test2/test.jmx")); +*/ + System.out.print("Has document: " + "/test2/test3/test3.jmx: "); + System.out.println(dsp.hasDocument("/test2/test3/test3.jmx")); + + System.out.print("Write document: " + "/test2/test3/test4/test5.jmx: "); + System.out.println(dsp.saveDocumentStream("/test-1.jmx", new ByteArrayInputStream(doc2), List.of("oxtrust-server","Shibboleth"))); +/* + System.out.print("Has document: " + "/test2/test3/test4/test5.jmx: "); + System.out.println(dsp.hasDocument("/test2/test3/test4/test5.jmx")); +*/ + System.out.print("Write document: " + "/test2/test3/test4/test5.jmx: "); + System.out.println(dsp.saveDocument("/test7.jmx", doc1, StandardCharsets.UTF_8, List.of("oxtrust-server","Shibboleth"))); +/* + System.out.print("Has document: " + "/test2/test3/test4/test5.jmx: "); + System.out.println(dsp.hasDocument("/test2/test3/test4/test5.jmx")); + + System.out.print("Read document: " + "/test2/test3/test4/test5.jmx: "); + System.out.println(dsp.readDocument("/test2/test3/test4/test5.jmx", StandardCharsets.UTF_8)); + + System.out.print("Read document: " + "/test2/test3/test4/test5.jmx: "); + System.out.println(IOUtils.toString(dsp.readDocumentAsStream("/test2/test3/test4/test5.jmx"), StandardCharsets.UTF_8)); + + System.out.print("Rename document: " + "/test2/test3/test4/test5.jmx: "); + System.out.println(dsp.renameDocument("/test2/test3/test4/test5.jmx", "/test2/test4/test5.jmx")); + + System.out.print("Has document: " + "/test2/test3/test4/test5.jmx: "); + System.out.println(dsp.hasDocument("/test2/test3/test4/test5.jmx")); + + System.out.print("Has document: " + "/test2/test4/test5.jmx: "); + System.out.println(dsp.hasDocument("/test2/test4/test5.jmx")); + + System.out.print("Remove document: " + "test2/test4/test5.jmx: "); + System.out.println(dsp.removeDocument("/test2/test4/test5.jmx")); + + System.out.print("Has document: " + "/test2/test4/test5.jmx: "); + System.out.println(dsp.hasDocument("/test2/test4/test5.jmx")); +*/ + } + +} diff --git a/core-java-ext/pom.xml b/core-java-ext/pom.xml new file mode 100644 index 000000000..064f83e3d --- /dev/null +++ b/core-java-ext/pom.xml @@ -0,0 +1,32 @@ + + + 4.0.0 + oxcore-java-ext + jar + Java extensions + + + org.gluu + oxcore + 4.5.6-SNAPSHOT + + + + + + src/main/resources + true + + **/*.xml + **/services/* + **/*.properties + + + + + + + + + \ No newline at end of file diff --git a/core-java-ext/src/main/java/org/gluu/i18n/ExtendedResourceBundle.java b/core-java-ext/src/main/java/org/gluu/i18n/ExtendedResourceBundle.java new file mode 100644 index 000000000..00a5dcc31 --- /dev/null +++ b/core-java-ext/src/main/java/org/gluu/i18n/ExtendedResourceBundle.java @@ -0,0 +1,116 @@ +package org.gluu.i18n; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.file.FileSystems; +import java.nio.file.Path; +import java.nio.file.StandardWatchEventKinds; +import java.nio.file.WatchKey; +import java.util.Collections; +import java.util.Date; +import java.util.Enumeration; +import java.util.Properties; +import java.util.ResourceBundle; +import java.util.Set; +import java.util.concurrent.locks.ReentrantLock; + +/** + * Custom i18n resource bundle with realod support + * + * @author Yuriy Movchan + * @version 02/07/2020 + */ +public class ExtendedResourceBundle extends ResourceBundle { + + private WatchKey watcher = null; + private Date watcherLastUpdate = new Date(); + + private String baseName; + private Path externalResource; + private Properties properties; + private Date lastUpdate; + + private final ReentrantLock updateLock = new ReentrantLock(); + + public ExtendedResourceBundle(String baseName, Path externalResource, Properties properties) throws IOException { + this.baseName = baseName; + this.externalResource = externalResource; + this.properties = properties; + + this.lastUpdate = new Date(); + + Path baseFolder = externalResource.getParent(); + this.watcher = baseFolder.register(FileSystems.getDefault().newWatchService(), StandardWatchEventKinds.ENTRY_MODIFY); + } + + @Override + protected Object handleGetObject(String key) { + if (properties != null) { + if ((externalResource != null) && (watcher != null)) { + checkWatcher(); + + updateLock.lock(); + try { + if (watcherLastUpdate.after(this.lastUpdate)) { + loadPropertiesFromFile(properties, externalResource); + this.lastUpdate = new Date(); + } + } catch (IOException ex) { + System.err.println("Failed to reload message bundle:" + externalResource); + } finally { + updateLock.unlock(); + } + } + + return properties.get(key); + } + + return parent.getObject(key); + } + + private void checkWatcher() { + if (!watcher.pollEvents().isEmpty()) { + watcherLastUpdate = new Date(); + } + } + + @Override + @SuppressWarnings({ "rawtypes", "unchecked" }) + public Enumeration getKeys() { + if (properties != null) { + Set keys = properties.keySet(); + return Collections.enumeration(keys); + } + + return parent.getKeys(); + } + + public String getBaseName() { + return baseName; + } + + protected static void loadPropertiesFromFile(Properties properties, Path externalResource) throws IOException { + if (externalResource == null) { + return; + } + + InputStreamReader input = null; + try { + File file = externalResource.toFile(); + if (file.exists()) { + input = new FileReader(externalResource.toFile()); + properties.load(input); // External bundle (will overwrite same keys). + } + } catch (IOException ex) { + System.err.println("Failed to load message bundle:" + externalResource); + throw ex; + } finally { + try { + input.close(); + } catch (Exception ex) {} + } + } + +} diff --git a/core-java-ext/src/main/java/org/gluu/i18n/ExtendedResourceBundleControlProvider.java b/core-java-ext/src/main/java/org/gluu/i18n/ExtendedResourceBundleControlProvider.java new file mode 100644 index 000000000..d22ed6e95 --- /dev/null +++ b/core-java-ext/src/main/java/org/gluu/i18n/ExtendedResourceBundleControlProvider.java @@ -0,0 +1,75 @@ +package org.gluu.i18n; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Locale; +import java.util.Properties; +import java.util.ResourceBundle; +import java.util.ResourceBundle.Control; +import java.util.spi.ResourceBundleControlProvider; + +/** + * Custom resource bundle loader java extension + * + * @author Yuriy Movchan + * @version 02/07/2020 + */ +public class ExtendedResourceBundleControlProvider implements ResourceBundleControlProvider { + + private static Path EXTERNAL_PATH; + + static { + if (System.getProperty("server.base") != null) { + Path customPath = Paths.get(System.getProperty("server.base") + "/custom/i18n"); + File file = customPath.toFile(); + if (file.exists() && file.isDirectory()) { + EXTERNAL_PATH = customPath; + } + } + } + + public ResourceBundle.Control getControl(String baseName) { + if (baseName.equals("javax.faces.Messages")) { + System.out.println("Preparing control to load bundle with baseName: " + baseName); + return new CustomControl(); + } + +// System.out.println("Using default control to load bundle with baseName: " + baseName); + + return null; + } + + protected static class CustomControl extends Control { + @Override + public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload) + throws IllegalAccessException, InstantiationException, IOException { + + String resourceName = toResourceName(toBundleName(baseName, locale), "properties"); + Properties properties = new Properties(); + + try (InputStream input = loader.getResourceAsStream(resourceName)) { + InputStreamReader inputReader = new InputStreamReader(input, "UTF-8"); + properties.load(inputReader); // Default (internal) bundle. + } + + if (properties.isEmpty()) { + System.out.println("Using default control to load bundle with baseName: " + baseName); + return null; + } + + Path externalResource = null; + if (EXTERNAL_PATH != null) { + externalResource = EXTERNAL_PATH.resolve(resourceName); + } + ExtendedResourceBundle.loadPropertiesFromFile(properties, externalResource); + + return new ExtendedResourceBundle(baseName, externalResource, properties); + } + + } + +} \ No newline at end of file diff --git a/core-java-ext/src/main/resources/META-INF/services/java.util.spi.ResourceBundleControlProvider b/core-java-ext/src/main/resources/META-INF/services/java.util.spi.ResourceBundleControlProvider new file mode 100644 index 000000000..7dd9f6737 --- /dev/null +++ b/core-java-ext/src/main/resources/META-INF/services/java.util.spi.ResourceBundleControlProvider @@ -0,0 +1 @@ +org.gluu.i18n.ExtendedResourceBundleControlProvider \ No newline at end of file diff --git a/core-script/pom.xml b/core-script/pom.xml new file mode 100644 index 000000000..f7d11cb2b --- /dev/null +++ b/core-script/pom.xml @@ -0,0 +1,105 @@ + + + 4.0.0 + oxcore-script + Reusable CDI Script implementation + + + org.gluu + oxcore + 4.5.6-SNAPSHOT + + + + ${maven.min-version} + + + + + + src/main/resources + true + + **/*.xml + **/services/* + **/*.properties + + + + + + + + + ${project.groupId} + oxcore-cdi + + + ${project.groupId} + gluu-orm-core + + + ${project.groupId} + gluu-orm-model + + + ${project.groupId} + oxcore-model + + + ${project.groupId} + oxcore-util + + + + + org.gluufederation + jython-standalone + + + + + javax.enterprise + cdi-api + provided + + + javax.validation + validation-api + provided + + + javax.servlet + javax.servlet-api + provided + + + + + com.google.guava + guava + + + + + org.slf4j + slf4j-api + provided + + + + javax.ws.rs + javax.ws.rs-api + provided + + + + + ${project.groupId} + gluu-orm-ldap + test + + + + \ No newline at end of file diff --git a/oxService/src/main/java/org/gluu/exception/PythonException.java b/core-script/src/main/java/org/gluu/exception/PythonException.java similarity index 100% rename from oxService/src/main/java/org/gluu/exception/PythonException.java rename to core-script/src/main/java/org/gluu/exception/PythonException.java diff --git a/oxService/src/main/java/org/gluu/model/custom/script/CustomScriptType.java b/core-script/src/main/java/org/gluu/model/custom/script/CustomScriptType.java similarity index 66% rename from oxService/src/main/java/org/gluu/model/custom/script/CustomScriptType.java rename to core-script/src/main/java/org/gluu/model/custom/script/CustomScriptType.java index 131e5e0b0..9f29d5165 100644 --- a/oxService/src/main/java/org/gluu/model/custom/script/CustomScriptType.java +++ b/core-script/src/main/java/org/gluu/model/custom/script/CustomScriptType.java @@ -6,9 +6,6 @@ package org.gluu.model.custom.script; -import java.util.HashMap; -import java.util.Map; - import org.gluu.model.custom.script.model.CustomScript; import org.gluu.model.custom.script.model.auth.AuthenticationCustomScript; import org.gluu.model.custom.script.type.BaseExternalType; @@ -16,24 +13,41 @@ import org.gluu.model.custom.script.type.auth.PersonAuthenticationType; import org.gluu.model.custom.script.type.authz.ConsentGatheringType; import org.gluu.model.custom.script.type.authz.DummyConsentGatheringType; +import org.gluu.model.custom.script.type.authzchallenge.AuthorizationChallengeType; +import org.gluu.model.custom.script.type.authzchallenge.DummyAuthorizationChallengeType; +import org.gluu.model.custom.script.type.ciba.DummyEndUserNotificationType; +import org.gluu.model.custom.script.type.ciba.EndUserNotificationType; import org.gluu.model.custom.script.type.client.ClientRegistrationType; import org.gluu.model.custom.script.type.client.DummyClientRegistrationType; +import org.gluu.model.custom.script.type.fido2.DummyFido2ExtensionType; +import org.gluu.model.custom.script.type.fido2.Fido2ExtensionType; import org.gluu.model.custom.script.type.id.DummyIdGeneratorType; import org.gluu.model.custom.script.type.id.IdGeneratorType; +import org.gluu.model.custom.script.type.idp.DummyIdpType; +import org.gluu.model.custom.script.type.idp.IdpType; import org.gluu.model.custom.script.type.introspection.DummyIntrospectionType; import org.gluu.model.custom.script.type.introspection.IntrospectionType; +import org.gluu.model.custom.script.type.logout.DummyEndSessionType; +import org.gluu.model.custom.script.type.logout.EndSessionType; import org.gluu.model.custom.script.type.owner.DummyResourceOwnerPasswordCredentialsType; import org.gluu.model.custom.script.type.owner.ResourceOwnerPasswordCredentialsType; +import org.gluu.model.custom.script.type.persistence.DummyPeristenceType; +import org.gluu.model.custom.script.type.persistence.PersistenceType; +import org.gluu.model.custom.script.type.postauthn.DummyPostAuthnType; +import org.gluu.model.custom.script.type.postauthn.PostAuthnType; +import org.gluu.model.custom.script.type.revoke.DummyRevokeTokenType; +import org.gluu.model.custom.script.type.revoke.RevokeTokenType; import org.gluu.model.custom.script.type.scim.DummyScimType; import org.gluu.model.custom.script.type.scim.ScimType; import org.gluu.model.custom.script.type.scope.DummyDynamicScopeType; import org.gluu.model.custom.script.type.scope.DynamicScopeType; import org.gluu.model.custom.script.type.session.ApplicationSessionType; import org.gluu.model.custom.script.type.session.DummyApplicationSessionType; -import org.gluu.model.custom.script.type.uma.UmaClaimsGatheringType; -import org.gluu.model.custom.script.type.uma.UmaDummyClaimsGatheringType; -import org.gluu.model.custom.script.type.uma.UmaDummyRptPolicyType; -import org.gluu.model.custom.script.type.uma.UmaRptPolicyType; +import org.gluu.model.custom.script.type.spontaneous.DummySpontaneousScopeType; +import org.gluu.model.custom.script.type.spontaneous.SpontaneousScopeType; +import org.gluu.model.custom.script.type.token.DummyUpdateTokenType; +import org.gluu.model.custom.script.type.token.UpdateTokenType; +import org.gluu.model.custom.script.type.uma.*; import org.gluu.model.custom.script.type.user.*; import org.gluu.persist.annotation.AttributeEnum; @@ -49,6 +63,7 @@ public enum CustomScriptType implements AttributeEnum { PERSON_AUTHENTICATION("person_authentication", "Person Authentication", PersonAuthenticationType.class, AuthenticationCustomScript.class, "PersonAuthentication", new DummyPersonAuthenticationType()), + AUTHORIZATION_CHALLENGE("authorization_challenge", "Authorization Challenge", AuthorizationChallengeType.class, CustomScript.class, "AuthorizationChallenge", new DummyAuthorizationChallengeType()), INTROSPECTION("introspection", "Introspection", IntrospectionType.class, CustomScript.class, "Introspection", new DummyIntrospectionType()), RESOURCE_OWNER_PASSWORD_CREDENTIALS("resource_owner_password_credentials", "Resource Owner Password Credentials", ResourceOwnerPasswordCredentialsType.class, CustomScript.class, "ResourceOwnerPasswordCredentials", new DummyResourceOwnerPasswordCredentialsType()), APPLICATION_SESSION("application_session", "Application Session", ApplicationSessionType.class, CustomScript.class, "ApplicationSession", @@ -64,13 +79,24 @@ public enum CustomScriptType implements AttributeEnum { new DummyIdGeneratorType()), UMA_RPT_POLICY("uma_rpt_policy", "UMA RPT Policies", UmaRptPolicyType.class, CustomScript.class, "UmaRptPolicy", new UmaDummyRptPolicyType()), + UMA_RPT_CLAIMS("uma_rpt_claims", "UMA RPT Claims", UmaRptClaimsType.class, CustomScript.class, "UmaRptClaims", new UmaDummyRptClaimsType()), UMA_CLAIMS_GATHERING("uma_claims_gathering", "UMA Claims Gathering", UmaClaimsGatheringType.class, CustomScript.class, "UmaClaimsGathering", new UmaDummyClaimsGatheringType()), CONSENT_GATHERING("consent_gathering", "Consent Gathering", ConsentGatheringType.class, CustomScript.class, "ConsentGathering", new DummyConsentGatheringType()), DYNAMIC_SCOPE("dynamic_scope", "Dynamic Scopes", DynamicScopeType.class, CustomScript.class, "DynamicScope", new DummyDynamicScopeType()), - SCIM("scim", "SCIM", ScimType.class, CustomScript.class, "ScimEventHandler", new DummyScimType()); + SPONTANEOUS_SCOPE("spontaneous_scope", "Spontaneous Scopes", SpontaneousScopeType.class, CustomScript.class, "SpontaneousScope", new DummySpontaneousScopeType()), + END_SESSION("end_session", "End Session", EndSessionType.class, CustomScript.class, "EndSession", new DummyEndSessionType()), + POST_AUTHN("post_authn", "Post Authentication", PostAuthnType.class, CustomScript.class, "PostAuthn", new DummyPostAuthnType()), + SCIM("scim", "SCIM", ScimType.class, CustomScript.class, "ScimEventHandler", new DummyScimType()), + CIBA_END_USER_NOTIFICATION("ciba_end_user_notification", "CIBA End User Notification", EndUserNotificationType.class, + CustomScript.class, "EndUserNotification", new DummyEndUserNotificationType()), + REVOKE_TOKEN("revoke_token", "Revoke Token", RevokeTokenType.class, CustomScript.class, "RevokeToken", new DummyRevokeTokenType()), + PERSISTENCE_EXTENSION("persistence_extension", "Persistence Extension", PersistenceType.class, CustomScript.class, "PersistenceExtension", new DummyPeristenceType()), + IDP("idp", "Idp Extension", IdpType.class, CustomScript.class, "IdpExtension", new DummyIdpType()), + UPDATE_TOKEN("update_token", "Update Token", UpdateTokenType.class, CustomScript.class, "UpdateToken", new DummyUpdateTokenType()), + FIDO2_EXTENSION("fido2_extension", "Fido2 Extension", Fido2ExtensionType.class, CustomScript.class, "Fido2Extension", new DummyFido2ExtensionType()); private String value; private String displayName; diff --git a/oxService/src/main/java/org/gluu/model/custom/script/conf/CustomScriptConfiguration.java b/core-script/src/main/java/org/gluu/model/custom/script/conf/CustomScriptConfiguration.java similarity index 100% rename from oxService/src/main/java/org/gluu/model/custom/script/conf/CustomScriptConfiguration.java rename to core-script/src/main/java/org/gluu/model/custom/script/conf/CustomScriptConfiguration.java diff --git a/oxService/src/main/java/org/gluu/model/custom/script/model/CustomScript.java b/core-script/src/main/java/org/gluu/model/custom/script/model/CustomScript.java similarity index 90% rename from oxService/src/main/java/org/gluu/model/custom/script/model/CustomScript.java rename to core-script/src/main/java/org/gluu/model/custom/script/model/CustomScript.java index a03d2f5cb..8e698cb2e 100644 --- a/oxService/src/main/java/org/gluu/model/custom/script/model/CustomScript.java +++ b/core-script/src/main/java/org/gluu/model/custom/script/model/CustomScript.java @@ -17,11 +17,11 @@ import org.gluu.model.SimpleCustomProperty; import org.gluu.model.SimpleExtendedCustomProperty; import org.gluu.model.custom.script.CustomScriptType; -import org.gluu.persist.model.base.BaseEntry; import org.gluu.persist.annotation.AttributeName; import org.gluu.persist.annotation.DataEntry; import org.gluu.persist.annotation.JsonObject; import org.gluu.persist.annotation.ObjectClass; +import org.gluu.persist.model.base.BaseEntry; import org.gluu.util.StringHelper; /** @@ -29,10 +29,12 @@ * * @author Yuriy Movchan Date: 12/03/2014 */ -@DataEntry(sortBy = "level") +@DataEntry(sortBy = "level", sortByName = "oxLevel") @ObjectClass("oxCustomScript") public class CustomScript extends BaseEntry { + private static final long serialVersionUID = -7507701887397812523L; + public static final String LOCATION_TYPE_MODEL_PROPERTY = "location_type"; public static final String LOCATION_PATH_MODEL_PROPERTY = "location_path"; @@ -61,12 +63,16 @@ public class CustomScript extends BaseEntry { @JsonObject @AttributeName(name = "oxModuleProperty") - private List moduleProperties; + private List moduleProperties = new ArrayList<>(); @JsonObject @AttributeName(name = "oxConfigurationProperty") private List configurationProperties; + @JsonObject + @AttributeName(name = "gluuPrivateProperty") + private List privateProperties; + @AttributeName(name = "oxLevel") private int level; @@ -105,6 +111,7 @@ public CustomScript(CustomScript customScript) { this.programmingLanguage = customScript.programmingLanguage; this.moduleProperties = customScript.moduleProperties; this.configurationProperties = customScript.configurationProperties; + this.privateProperties = customScript.privateProperties; this.level = customScript.level; this.revision = customScript.revision; this.enabled = customScript.enabled; @@ -149,6 +156,13 @@ public void setDescription(String description) { } public String getScript() { + + if(script==null && scriptType==CustomScriptType.PERSON_AUTHENTICATION){ + script=ScriptTemplate.AUTHEN.getValue(); + } + else if(script==null && scriptType!=CustomScriptType.PERSON_AUTHENTICATION){ + script=ScriptTemplate.NO_AUTHEN.getValue(); + } return script; } @@ -188,6 +202,14 @@ public void setConfigurationProperties(List proper this.configurationProperties = properties; } + public List getPrivateProperties() { + return privateProperties; + } + + public void setPrivateProperties(List properties) { + this.privateProperties = properties; + } + public int getLevel() { return level; } diff --git a/oxService/src/main/java/org/gluu/model/custom/script/model/ScriptError.java b/core-script/src/main/java/org/gluu/model/custom/script/model/ScriptError.java similarity index 100% rename from oxService/src/main/java/org/gluu/model/custom/script/model/ScriptError.java rename to core-script/src/main/java/org/gluu/model/custom/script/model/ScriptError.java diff --git a/core-script/src/main/java/org/gluu/model/custom/script/model/ScriptTemplate.java b/core-script/src/main/java/org/gluu/model/custom/script/model/ScriptTemplate.java new file mode 100644 index 000000000..06aa3920d --- /dev/null +++ b/core-script/src/main/java/org/gluu/model/custom/script/model/ScriptTemplate.java @@ -0,0 +1,94 @@ +package org.gluu.model.custom.script.model; + +public enum ScriptTemplate { + + AUTHEN( "from org.gluu.service.cdi.util import CdiUtil\n" + + "from org.gluu.model.custom.script.type.auth import PersonAuthenticationType\n" + + "\n" + + "import java\n" + + "\n" + + "class PersonAuthentication(PersonAuthenticationType):\n" + + " def __init__(self, currentTimeMillis):\n" + + " self.currentTimeMillis = currentTimeMillis\n" + + "\n" + + " def init(self, configurationAttributes):\n" + + " return True \n" + + "\n" + + " def destroy(self, configurationAttributes):\n" + + " return True\n" + + "\n" + + " def getApiVersion(self):\n" + + " return 1\n" + + "\n" + + " def isValidAuthenticationMethod(self, usageType, configurationAttributes):\n" + + " return True\n" + + "\n" + + " def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\n" + + " return None\n" + + "\n" + + " def authenticate(self, configurationAttributes, requestParameters, step):\n" + + " return True\n" + + "\n" + + " def prepareForStep(self, configurationAttributes, requestParameters, step):\n" + + " return True\n" + + "\n" + + " def getExtraParametersForStep(self, configurationAttributes, step):\n" + + " return None\n" + + "\n" + + " def getCountAuthenticationSteps(self, configurationAttributes):\n" + + " return 1\n" + + "\n" + + " def getPageForStep(self, configurationAttributes, step):\n" + + " return \"\"\n" + + "\n" + + " def logout(self, configurationAttributes, requestParameters):\n" + + " return True\n"), + NO_AUTHEN("from org.gluu.service.cdi.util import CdiUtil\n" + + "from org.gluu.oxauth.security import Identity\n" + + "from org.gluu.model.custom.script.type.authz import ConsentGatheringType\n" + + "from org.gluu.util import StringHelper\n" + + "\n" + + "import java\n" + + "import random\n" + + "\n" + + "class SampleScript(ConsentGatheringType):\n" + + "\n" + + " def __init__(self, currentTimeMillis):\n" + + "\n" + + " def init(self, configurationAttributes):\n" + + " return True\n" + + "\n" + + " def destroy(self, configurationAttributes):\n" + + " return True\n" + + "\n" + + " def getApiVersion(self):\n" + + " return 1\n" + + "\n" + + " \n" + + " def authorize(self, step, context): \n" + + " return True\n" + + "\n" + + " def getNextStep(self, step, context):\n" + + " return -1\n" + + "\n" + + " def prepareForStep(self, step, context):\n" + + " return True\n" + + "\n" + + " def getStepsCount(self, context):\n" + + " return 2\n" + + "\n" + + " def getPageForStep(self, step, context):\n" + + " return \"\"\n"); + + + private final String value; + + + ScriptTemplate(String value) { + this.value = value; + } + + public String getValue() { + return this.value; + } +} diff --git a/oxService/src/main/java/org/gluu/model/custom/script/model/auth/AuthenticationCustomScript.java b/core-script/src/main/java/org/gluu/model/custom/script/model/auth/AuthenticationCustomScript.java similarity index 100% rename from oxService/src/main/java/org/gluu/model/custom/script/model/auth/AuthenticationCustomScript.java rename to core-script/src/main/java/org/gluu/model/custom/script/model/auth/AuthenticationCustomScript.java diff --git a/oxService/src/main/java/org/gluu/model/custom/script/model/bind/BindCredentials.java b/core-script/src/main/java/org/gluu/model/custom/script/model/bind/BindCredentials.java similarity index 100% rename from oxService/src/main/java/org/gluu/model/custom/script/model/bind/BindCredentials.java rename to core-script/src/main/java/org/gluu/model/custom/script/model/bind/BindCredentials.java diff --git a/oxService/src/main/java/org/gluu/model/custom/script/type/BaseExternalType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/BaseExternalType.java similarity index 77% rename from oxService/src/main/java/org/gluu/model/custom/script/type/BaseExternalType.java rename to core-script/src/main/java/org/gluu/model/custom/script/type/BaseExternalType.java index db4773c4e..59557c646 100644 --- a/oxService/src/main/java/org/gluu/model/custom/script/type/BaseExternalType.java +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/BaseExternalType.java @@ -7,7 +7,7 @@ import java.util.Map; import org.gluu.model.SimpleCustomProperty; - +import org.gluu.model.custom.script.model.CustomScript; /** * Base interface for external python script * @@ -16,6 +16,8 @@ public interface BaseExternalType { boolean init(Map configurationAttributes); + + boolean init(CustomScript customScript, Map configurationAttributes); boolean destroy(Map configurationAttributes); diff --git a/oxService/src/main/java/org/gluu/model/custom/script/type/auth/DummyPersonAuthenticationType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/auth/DummyPersonAuthenticationType.java similarity index 85% rename from oxService/src/main/java/org/gluu/model/custom/script/type/auth/DummyPersonAuthenticationType.java rename to core-script/src/main/java/org/gluu/model/custom/script/type/auth/DummyPersonAuthenticationType.java index 5b73f53bd..7a481ce7f 100644 --- a/oxService/src/main/java/org/gluu/model/custom/script/type/auth/DummyPersonAuthenticationType.java +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/auth/DummyPersonAuthenticationType.java @@ -11,7 +11,7 @@ import org.gluu.model.AuthenticationScriptUsageType; import org.gluu.model.SimpleCustomProperty; - +import org.gluu.model.custom.script.model.CustomScript; /** * Dummy implementation of interface PersonAuthenticationType * @@ -23,7 +23,10 @@ public class DummyPersonAuthenticationType implements PersonAuthenticationType { public boolean init(Map configurationAttributes) { return true; } - + @Override + public boolean init(CustomScript customScript, Map configurationAttributes) { + return true; + } @Override public boolean destroy(Map configurationAttributes) { return true; @@ -85,7 +88,7 @@ public int getApiVersion() { } @Override - public Map getAuthenticationMethodClaims() { + public Map getAuthenticationMethodClaims(Map configurationAttribute) { return null; } diff --git a/oxService/src/main/java/org/gluu/model/custom/script/type/auth/PersonAuthenticationType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/auth/PersonAuthenticationType.java similarity index 92% rename from oxService/src/main/java/org/gluu/model/custom/script/type/auth/PersonAuthenticationType.java rename to core-script/src/main/java/org/gluu/model/custom/script/type/auth/PersonAuthenticationType.java index fbd285e7d..fcb478ac6 100644 --- a/oxService/src/main/java/org/gluu/model/custom/script/type/auth/PersonAuthenticationType.java +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/auth/PersonAuthenticationType.java @@ -6,13 +6,13 @@ package org.gluu.model.custom.script.type.auth; +import java.util.List; +import java.util.Map; + import org.gluu.model.AuthenticationScriptUsageType; import org.gluu.model.SimpleCustomProperty; import org.gluu.model.custom.script.type.BaseExternalType; -import java.util.List; -import java.util.Map; - /** * Base interface for external authentication python script * @@ -41,5 +41,5 @@ String getAlternativeAuthenticationMethod(AuthenticationScriptUsageType usageTyp String getLogoutExternalUrl(Map configurationAttributes, Map requestParameters); - Map getAuthenticationMethodClaims(); + Map getAuthenticationMethodClaims(Map configurationAttributes); } diff --git a/oxService/src/main/java/org/gluu/model/custom/script/type/authz/ConsentGatheringType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/authz/ConsentGatheringType.java similarity index 100% rename from oxService/src/main/java/org/gluu/model/custom/script/type/authz/ConsentGatheringType.java rename to core-script/src/main/java/org/gluu/model/custom/script/type/authz/ConsentGatheringType.java diff --git a/oxService/src/main/java/org/gluu/model/custom/script/type/authz/DummyConsentGatheringType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/authz/DummyConsentGatheringType.java similarity index 84% rename from oxService/src/main/java/org/gluu/model/custom/script/type/authz/DummyConsentGatheringType.java rename to core-script/src/main/java/org/gluu/model/custom/script/type/authz/DummyConsentGatheringType.java index ae5217021..fd2434973 100644 --- a/oxService/src/main/java/org/gluu/model/custom/script/type/authz/DummyConsentGatheringType.java +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/authz/DummyConsentGatheringType.java @@ -3,7 +3,7 @@ import java.util.Map; import org.gluu.model.SimpleCustomProperty; - +import org.gluu.model.custom.script.model.CustomScript; /** * Dummy implementation of interface AuthorizationType * @@ -15,7 +15,10 @@ public class DummyConsentGatheringType implements ConsentGatheringType { public boolean init(Map configurationAttributes) { return false; } - + @Override + public boolean init(CustomScript customScript, Map configurationAttributes) { + return true; + } @Override public boolean destroy(Map configurationAttributes) { return false; diff --git a/core-script/src/main/java/org/gluu/model/custom/script/type/authzchallenge/AuthorizationChallengeType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/authzchallenge/AuthorizationChallengeType.java new file mode 100644 index 000000000..f9f3f0be8 --- /dev/null +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/authzchallenge/AuthorizationChallengeType.java @@ -0,0 +1,11 @@ +package org.gluu.model.custom.script.type.authzchallenge; + +import org.gluu.model.custom.script.type.BaseExternalType; + +/** + * @author Yuriy Z + */ +public interface AuthorizationChallengeType extends BaseExternalType { + + boolean authorize(Object context); +} diff --git a/core-script/src/main/java/org/gluu/model/custom/script/type/authzchallenge/DummyAuthorizationChallengeType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/authzchallenge/DummyAuthorizationChallengeType.java new file mode 100644 index 000000000..e33d5213a --- /dev/null +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/authzchallenge/DummyAuthorizationChallengeType.java @@ -0,0 +1,37 @@ +package org.gluu.model.custom.script.type.authzchallenge; + +import org.gluu.model.SimpleCustomProperty; +import org.gluu.model.custom.script.model.CustomScript; + +import java.util.Map; + +/** + * @author Yuriy Z + */ +public class DummyAuthorizationChallengeType implements AuthorizationChallengeType { + + @Override + public boolean authorize(Object context) { + return false; + } + + @Override + public boolean init(Map configurationAttributes) { + return false; + } + + @Override + public boolean init(CustomScript customScript, Map configurationAttributes) { + return false; + } + + @Override + public boolean destroy(Map configurationAttributes) { + return false; + } + + @Override + public int getApiVersion() { + return 1; + } +} diff --git a/core-script/src/main/java/org/gluu/model/custom/script/type/ciba/DummyEndUserNotificationType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/ciba/DummyEndUserNotificationType.java new file mode 100644 index 000000000..d496a97c6 --- /dev/null +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/ciba/DummyEndUserNotificationType.java @@ -0,0 +1,44 @@ +/* + * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2014, Gluu + */ + +package org.gluu.model.custom.script.type.ciba; + +import java.util.Map; + +import org.gluu.model.SimpleCustomProperty; +import org.gluu.model.custom.script.model.CustomScript; + +/** + * Dummy implementation of interface EndUserNotificationType + * + * @author Milton BO Date: 04/22/2020 + */ +public class DummyEndUserNotificationType implements EndUserNotificationType { + + @Override + public boolean init(Map configurationAttributes) { + return true; + } + @Override + public boolean init(CustomScript customScript, Map configurationAttributes) { + return true; + } + @Override + public boolean destroy(Map configurationAttributes) { + return true; + } + + @Override + public int getApiVersion() { + return 1; + } + + @Override + public boolean notifyEndUser(Object context) { + return false; + } + +} diff --git a/core-script/src/main/java/org/gluu/model/custom/script/type/ciba/EndUserNotificationType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/ciba/EndUserNotificationType.java new file mode 100644 index 000000000..dc86bfde7 --- /dev/null +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/ciba/EndUserNotificationType.java @@ -0,0 +1,20 @@ +/* + * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2014, Gluu + */ + +package org.gluu.model.custom.script.type.ciba; + +import org.gluu.model.custom.script.type.BaseExternalType; + +/** + * Base interface for external authentication python script + * + * @author Milton BO Date: 04/22/2020 + */ +public interface EndUserNotificationType extends BaseExternalType { + + boolean notifyEndUser(Object context); + +} diff --git a/oxService/src/main/java/org/gluu/model/custom/script/type/client/ClientRegistrationType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/client/ClientRegistrationType.java similarity index 87% rename from oxService/src/main/java/org/gluu/model/custom/script/type/client/ClientRegistrationType.java rename to core-script/src/main/java/org/gluu/model/custom/script/type/client/ClientRegistrationType.java index ab9bd366f..06f802670 100644 --- a/oxService/src/main/java/org/gluu/model/custom/script/type/client/ClientRegistrationType.java +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/client/ClientRegistrationType.java @@ -6,11 +6,11 @@ package org.gluu.model.custom.script.type.client; -import java.util.Map; - import org.gluu.model.SimpleCustomProperty; import org.gluu.model.custom.script.type.BaseExternalType; +import java.util.Map; + /** * Base interface for external custom client registration python script * @@ -22,4 +22,8 @@ public interface ClientRegistrationType extends BaseExternalType { public boolean updateClient(Object registerRequest, Object client, Map configurationAttributes); + String getSoftwareStatementHmacSecret(Object context); + + String getSoftwareStatementJwks(Object context); + } diff --git a/oxService/src/main/java/org/gluu/model/custom/script/type/client/DummyClientRegistrationType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/client/DummyClientRegistrationType.java similarity index 71% rename from oxService/src/main/java/org/gluu/model/custom/script/type/client/DummyClientRegistrationType.java rename to core-script/src/main/java/org/gluu/model/custom/script/type/client/DummyClientRegistrationType.java index eeb30cd69..cbf77668b 100644 --- a/oxService/src/main/java/org/gluu/model/custom/script/type/client/DummyClientRegistrationType.java +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/client/DummyClientRegistrationType.java @@ -4,10 +4,10 @@ * Copyright (c) 2014, Gluu */package org.gluu.model.custom.script.type.client; -import java.util.Map; - import org.gluu.model.SimpleCustomProperty; +import org.gluu.model.custom.script.model.CustomScript; +import java.util.Map; /** * Dummy implementation of interface ClientRegistrationType * @@ -19,7 +19,10 @@ public class DummyClientRegistrationType implements ClientRegistrationType { public boolean init(Map configurationAttributes) { return true; } - + @Override + public boolean init(CustomScript customScript, Map configurationAttributes) { + return true; + } @Override public boolean destroy(Map configurationAttributes) { return true; @@ -40,4 +43,13 @@ public boolean updateClient(Object registerRequest, Object client, Map configurationAttributes) { + return true; + } + + @Override + public boolean init(CustomScript customScript, Map configurationAttributes) { + return true; + } + + @Override + public boolean destroy(Map configurationAttributes) { + return true; + } + + @Override + public int getApiVersion() { + return 1; + } + + @Override + public boolean registerAttestationStart(Object paramAsJsonNode, Object context) { + return false; + } + + @Override + public boolean registerAttestationFinish(Object paramAsJsonNode, Object context) { + return false; + } + + @Override + public boolean verifyAttestationStart(Object paramAsJsonNode, Object context) { + return false; + } + + @Override + public boolean verifyAttestationFinish(Object paramAsJsonNode, Object context) { + return false; + } + + @Override + public boolean authenticateAssertionStart(Object paramAsJsonNode, Object context) { + return false; + } + + @Override + public boolean authenticateAssertionFinish(Object paramAsJsonNode, Object context) { + return false; + } + + @Override + public boolean verifyAssertionStart(Object paramAsJsonNode, Object context) { + return false; + } + + @Override + public boolean verifyAssertionFinish(Object paramAsJsonNode, Object context) { + return false; + } + +} diff --git a/core-script/src/main/java/org/gluu/model/custom/script/type/fido2/Fido2ExtensionType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/fido2/Fido2ExtensionType.java new file mode 100644 index 000000000..d9c9eedd6 --- /dev/null +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/fido2/Fido2ExtensionType.java @@ -0,0 +1,24 @@ +/* + * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Gluu + */ + +package org.gluu.model.custom.script.type.fido2; + +import org.gluu.model.custom.script.type.BaseExternalType; + +public interface Fido2ExtensionType extends BaseExternalType { + + boolean registerAttestationStart(Object paramAsJsonNode, Object context); + boolean registerAttestationFinish(Object paramAsJsonNode, Object context); + + boolean verifyAttestationStart(Object paramAsJsonNode, Object context); + boolean verifyAttestationFinish(Object paramAsJsonNode, Object context); + + boolean authenticateAssertionStart(Object paramAsJsonNode, Object context); + boolean authenticateAssertionFinish(Object paramAsJsonNode, Object context); + + boolean verifyAssertionStart(Object paramAsJsonNode, Object context); + boolean verifyAssertionFinish(Object paramAsJsonNode, Object context); +} diff --git a/oxService/src/main/java/org/gluu/model/custom/script/type/id/DummyIdGeneratorType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/id/DummyIdGeneratorType.java similarity index 81% rename from oxService/src/main/java/org/gluu/model/custom/script/type/id/DummyIdGeneratorType.java rename to core-script/src/main/java/org/gluu/model/custom/script/type/id/DummyIdGeneratorType.java index 9de8df3f5..8e39a5503 100644 --- a/oxService/src/main/java/org/gluu/model/custom/script/type/id/DummyIdGeneratorType.java +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/id/DummyIdGeneratorType.java @@ -7,7 +7,7 @@ import java.util.Map; import org.gluu.model.SimpleCustomProperty; - +import org.gluu.model.custom.script.model.CustomScript; /** * Dummy implementation of interface IdGeneratorType * @@ -19,7 +19,10 @@ public class DummyIdGeneratorType implements IdGeneratorType { public boolean init(Map configurationAttributes) { return true; } - + @Override + public boolean init(CustomScript customScript, Map configurationAttributes) { + return true; + } @Override public boolean destroy(Map configurationAttributes) { return true; diff --git a/oxService/src/main/java/org/gluu/model/custom/script/type/id/IdGeneratorType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/id/IdGeneratorType.java similarity index 100% rename from oxService/src/main/java/org/gluu/model/custom/script/type/id/IdGeneratorType.java rename to core-script/src/main/java/org/gluu/model/custom/script/type/id/IdGeneratorType.java diff --git a/core-script/src/main/java/org/gluu/model/custom/script/type/idp/DummyIdpType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/idp/DummyIdpType.java new file mode 100644 index 000000000..c8d722d6b --- /dev/null +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/idp/DummyIdpType.java @@ -0,0 +1,53 @@ +/* + * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Gluu + */package org.gluu.model.custom.script.type.idp; + +import java.util.Map; + +import org.gluu.model.SimpleCustomProperty; +import org.gluu.model.custom.script.model.CustomScript; +/** + * Dummy implementation of interface IdpType + * + * @author Yuriy Movchan Date: 06/18/2020 + */ +public class DummyIdpType implements IdpType { + + @Override + public boolean init(Map configurationAttributes) { + return true; + } + + @Override + public boolean init(CustomScript customScript, Map configurationAttributes) { + return true; + } + + @Override + public boolean destroy(Map configurationAttributes) { + return true; + } + + @Override + public int getApiVersion() { + return 1; + } + + @Override + public boolean translateAttributes(Object context, Map configurationAttributes) { + return false; + } + + @Override + public boolean updateAttributes(Object context, Map configurationAttributes) { + return false; + } + + @Override + public boolean postAuthentication(Object context, Map configurationAttributes) { + return true; + } + +} diff --git a/core-script/src/main/java/org/gluu/model/custom/script/type/idp/IdpType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/idp/IdpType.java new file mode 100644 index 000000000..3a1869e0b --- /dev/null +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/idp/IdpType.java @@ -0,0 +1,27 @@ +/* + * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2014, Gluu + */ + +package org.gluu.model.custom.script.type.idp; + +import java.util.Map; + +import org.gluu.model.SimpleCustomProperty; +import org.gluu.model.custom.script.type.BaseExternalType; + +/** + * Base interface for IDP script + * + * @author Yuriy Movchan Date: 06/18/2020 + */ +public interface IdpType extends BaseExternalType { + + boolean translateAttributes(Object context, Map configurationAttributes); + + boolean updateAttributes(Object context, Map configurationAttributes); + + boolean postAuthentication(Object context, Map configurationAttributes); + +} diff --git a/oxService/src/main/java/org/gluu/model/custom/script/type/introspection/DummyIntrospectionType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/introspection/DummyIntrospectionType.java similarity index 76% rename from oxService/src/main/java/org/gluu/model/custom/script/type/introspection/DummyIntrospectionType.java rename to core-script/src/main/java/org/gluu/model/custom/script/type/introspection/DummyIntrospectionType.java index 25419e1b9..a7dcb07d4 100644 --- a/oxService/src/main/java/org/gluu/model/custom/script/type/introspection/DummyIntrospectionType.java +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/introspection/DummyIntrospectionType.java @@ -3,7 +3,7 @@ import java.util.Map; import org.gluu.model.SimpleCustomProperty; - +import org.gluu.model.custom.script.model.CustomScript; /** * @author Yuriy Zabrovarnyy */ @@ -12,7 +12,10 @@ public class DummyIntrospectionType implements IntrospectionType { public boolean init(Map configurationAttributes) { return true; } - + @Override + public boolean init(CustomScript customScript, Map configurationAttributes) { + return true; + } @Override public boolean destroy(Map configurationAttributes) { return true; diff --git a/oxService/src/main/java/org/gluu/model/custom/script/type/introspection/IntrospectionType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/introspection/IntrospectionType.java similarity index 100% rename from oxService/src/main/java/org/gluu/model/custom/script/type/introspection/IntrospectionType.java rename to core-script/src/main/java/org/gluu/model/custom/script/type/introspection/IntrospectionType.java diff --git a/core-script/src/main/java/org/gluu/model/custom/script/type/logout/DummyEndSessionType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/logout/DummyEndSessionType.java new file mode 100644 index 000000000..d8efad8c4 --- /dev/null +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/logout/DummyEndSessionType.java @@ -0,0 +1,34 @@ +package org.gluu.model.custom.script.type.logout; + +import java.util.Map; + +import org.gluu.model.SimpleCustomProperty; +import org.gluu.model.custom.script.model.CustomScript; + +/** + * @author Yuriy Zabrovarnyy + */ +public class DummyEndSessionType implements EndSessionType { + @Override + public boolean init(Map configurationAttributes) { + return true; + } + @Override + public boolean init(CustomScript customScript, Map configurationAttributes) { + return true; + } + @Override + public boolean destroy(Map configurationAttributes) { + return true; + } + + @Override + public int getApiVersion() { + return 1; + } + + @Override + public String getFrontchannelHtml(Object context) { + return null; + } +} diff --git a/core-script/src/main/java/org/gluu/model/custom/script/type/logout/EndSessionType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/logout/EndSessionType.java new file mode 100644 index 000000000..d92a4c29f --- /dev/null +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/logout/EndSessionType.java @@ -0,0 +1,11 @@ +package org.gluu.model.custom.script.type.logout; + +import org.gluu.model.custom.script.type.BaseExternalType; + +/** + * @author Yuriy Zabrovarnyy + */ +public interface EndSessionType extends BaseExternalType { + + String getFrontchannelHtml(Object context); +} diff --git a/oxService/src/main/java/org/gluu/model/custom/script/type/owner/DummyResourceOwnerPasswordCredentialsType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/owner/DummyResourceOwnerPasswordCredentialsType.java similarity index 76% rename from oxService/src/main/java/org/gluu/model/custom/script/type/owner/DummyResourceOwnerPasswordCredentialsType.java rename to core-script/src/main/java/org/gluu/model/custom/script/type/owner/DummyResourceOwnerPasswordCredentialsType.java index 1a612988a..18fe2be02 100644 --- a/oxService/src/main/java/org/gluu/model/custom/script/type/owner/DummyResourceOwnerPasswordCredentialsType.java +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/owner/DummyResourceOwnerPasswordCredentialsType.java @@ -3,6 +3,7 @@ import java.util.Map; import org.gluu.model.SimpleCustomProperty; +import org.gluu.model.custom.script.model.CustomScript; /** * @author Yuriy Zabrovarnyy @@ -12,7 +13,10 @@ public class DummyResourceOwnerPasswordCredentialsType implements ResourceOwnerP public boolean init(Map configurationAttributes) { return true; } - + @Override + public boolean init(CustomScript customScript, Map configurationAttributes) { + return true; + } @Override public boolean destroy(Map configurationAttributes) { return true; diff --git a/oxService/src/main/java/org/gluu/model/custom/script/type/owner/ResourceOwnerPasswordCredentialsType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/owner/ResourceOwnerPasswordCredentialsType.java similarity index 100% rename from oxService/src/main/java/org/gluu/model/custom/script/type/owner/ResourceOwnerPasswordCredentialsType.java rename to core-script/src/main/java/org/gluu/model/custom/script/type/owner/ResourceOwnerPasswordCredentialsType.java diff --git a/core-script/src/main/java/org/gluu/model/custom/script/type/persistence/DummyPeristenceType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/persistence/DummyPeristenceType.java new file mode 100644 index 000000000..ff18e9eca --- /dev/null +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/persistence/DummyPeristenceType.java @@ -0,0 +1,56 @@ +/* + * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Gluu + */package org.gluu.model.custom.script.type.persistence; + +import java.util.Map; + +import org.gluu.model.SimpleCustomProperty; +import org.gluu.model.custom.script.model.CustomScript; +/** + * Dummy implementation of interface DynamicPeristanceType + * + * @author Yuriy Movchan Date: 06/04/2020 + */ +public class DummyPeristenceType implements PersistenceType { + + @Override + public boolean init(Map configurationAttributes) { + return true; + } + + @Override + public boolean init(CustomScript customScript, Map configurationAttributes) { + return true; + } + + @Override + public boolean destroy(Map configurationAttributes) { + return true; + } + + @Override + public int getApiVersion() { + return 1; + } + + @Override + public void onAfterCreate(Object context, Map configurationAttributes) { + } + + @Override + public void onAfterDestroy(Object context, Map configurationAttributes) { + } + + @Override + public String createHashedPassword(String credential) { + return credential; + } + + @Override + public boolean compareHashedPasswords(String credential, String storedCredential) { + return false; + } + +} diff --git a/core-script/src/main/java/org/gluu/model/custom/script/type/persistence/PersistenceType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/persistence/PersistenceType.java new file mode 100644 index 000000000..32cbbb58d --- /dev/null +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/persistence/PersistenceType.java @@ -0,0 +1,25 @@ +/* + * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2014, Gluu + */ + +package org.gluu.model.custom.script.type.persistence; + +import java.util.Map; + +import org.gluu.model.SimpleCustomProperty; +import org.gluu.model.custom.script.type.BaseExternalType; +import org.gluu.persist.extension.PersistenceExtension; + +/** + * Base interface for persistence script + * + * @author Yuriy Movchan Date: 06/04/2020 + */ +public interface PersistenceType extends BaseExternalType, PersistenceExtension { + + void onAfterCreate(Object context, Map configurationAttributes); + void onAfterDestroy(Object context, Map configurationAttributes); + +} diff --git a/core-script/src/main/java/org/gluu/model/custom/script/type/postauthn/DummyPostAuthnType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/postauthn/DummyPostAuthnType.java new file mode 100644 index 000000000..d94fcde65 --- /dev/null +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/postauthn/DummyPostAuthnType.java @@ -0,0 +1,41 @@ +package org.gluu.model.custom.script.type.postauthn; + +import java.util.Map; + +import org.gluu.model.SimpleCustomProperty; +import org.gluu.model.custom.script.model.CustomScript; + +/** + * @author Yuriy Zabrovarnyy + */ +public class DummyPostAuthnType implements PostAuthnType { + @Override + public boolean forceReAuthentication(Object context) { + return false; + } + + @Override + public boolean forceAuthorization(Object context) { + return false; + } + + @Override + public boolean init(Map configurationAttributes) { + return true; + } + + @Override + public boolean init(CustomScript customScript, Map configurationAttributes) { + return true; + } + + @Override + public boolean destroy(Map configurationAttributes) { + return true; + } + + @Override + public int getApiVersion() { + return 0; + } +} diff --git a/core-script/src/main/java/org/gluu/model/custom/script/type/postauthn/PostAuthnType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/postauthn/PostAuthnType.java new file mode 100644 index 000000000..63e6efea1 --- /dev/null +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/postauthn/PostAuthnType.java @@ -0,0 +1,13 @@ +package org.gluu.model.custom.script.type.postauthn; + +import org.gluu.model.custom.script.type.BaseExternalType; + +/** + * @author Yuriy Zabrovarnyy + */ +public interface PostAuthnType extends BaseExternalType { + + boolean forceReAuthentication(Object context); + + boolean forceAuthorization(Object context); +} diff --git a/core-script/src/main/java/org/gluu/model/custom/script/type/revoke/DummyRevokeTokenType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/revoke/DummyRevokeTokenType.java new file mode 100644 index 000000000..4aba8086b --- /dev/null +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/revoke/DummyRevokeTokenType.java @@ -0,0 +1,36 @@ +package org.gluu.model.custom.script.type.revoke; + +import org.gluu.model.SimpleCustomProperty; +import org.gluu.model.custom.script.model.CustomScript; + +import java.util.Map; + +/** + * @author Yuriy Zabrovarnyy + */ +public class DummyRevokeTokenType implements RevokeTokenType { + @Override + public boolean init(Map configurationAttributes) { + return true; + } + + @Override + public boolean init(CustomScript customScript, Map configurationAttributes) { + return true; + } + + @Override + public boolean destroy(Map configurationAttributes) { + return true; + } + + @Override + public int getApiVersion() { + return 1; + } + + @Override + public boolean revoke(Object context) { + return true; + } +} diff --git a/core-script/src/main/java/org/gluu/model/custom/script/type/revoke/RevokeTokenType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/revoke/RevokeTokenType.java new file mode 100644 index 000000000..7be84f194 --- /dev/null +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/revoke/RevokeTokenType.java @@ -0,0 +1,11 @@ +package org.gluu.model.custom.script.type.revoke; + +import org.gluu.model.custom.script.type.BaseExternalType; + +/** + * @author Yuriy Zabrovarnyy + */ +public interface RevokeTokenType extends BaseExternalType { + + boolean revoke(Object context); +} diff --git a/oxService/src/main/java/org/gluu/model/custom/script/type/scim/DummyScimType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/scim/DummyScimType.java similarity index 64% rename from oxService/src/main/java/org/gluu/model/custom/script/type/scim/DummyScimType.java rename to core-script/src/main/java/org/gluu/model/custom/script/type/scim/DummyScimType.java index 396623201..60d157c1a 100644 --- a/oxService/src/main/java/org/gluu/model/custom/script/type/scim/DummyScimType.java +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/scim/DummyScimType.java @@ -1,16 +1,14 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ package org.gluu.model.custom.script.type.scim; import java.util.Map; import org.gluu.model.SimpleCustomProperty; +import org.gluu.model.custom.script.model.CustomScript; + +import javax.ws.rs.core.Response; /** - * @author Val Pecaoco + * @author jgomer2001 */ public class DummyScimType implements ScimType { @@ -19,6 +17,11 @@ public boolean init(Map configurationAttributes) { return true; } + @Override + public boolean init(CustomScript customScript, Map configurationAttributes) { + return true; + } + @Override public boolean destroy(Map configurationAttributes) { return true; @@ -89,4 +92,34 @@ public boolean postDeleteGroup(Object user, Map co return false; } + @Override + public boolean getUser(Object user, Map configurationAttributes) { + return false; + } + + @Override + public boolean getGroup(Object group, Map configurationAttributes) { + return false; + } + + @Override + public boolean postSearchUsers(Object results, Map configurationAttributes) { + return false; + } + + @Override + public boolean postSearchGroups(Object results, Map configurationAttributes) { + return false; + } + + @Override + public Response manageResourceOperation(Object context, Object entity, Object payload, Map configurationAttributes) { + return null; + } + + @Override + public Response manageSearchOperation(Object context, Object searchRequest, Map configurationAttributes) { + return null; + } + } diff --git a/core-script/src/main/java/org/gluu/model/custom/script/type/scim/ScimType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/scim/ScimType.java new file mode 100644 index 000000000..8d6f35c22 --- /dev/null +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/scim/ScimType.java @@ -0,0 +1,51 @@ +package org.gluu.model.custom.script.type.scim; + +import java.util.Map; + +import org.gluu.model.SimpleCustomProperty; +import org.gluu.model.custom.script.type.BaseExternalType; + +import javax.ws.rs.core.Response; + +/** + * @author jgomer2001 + */ +public interface ScimType extends BaseExternalType { + + boolean createUser(Object user, Map configurationAttributes); + + boolean postCreateUser(Object user, Map configurationAttributes); + + boolean updateUser(Object user, Map configurationAttributes); + + boolean postUpdateUser(Object user, Map configurationAttributes); + + boolean deleteUser(Object user, Map configurationAttributes); + + boolean postDeleteUser(Object user, Map configurationAttributes); + + boolean createGroup(Object group, Map configurationAttributes); + + boolean postCreateGroup(Object group, Map configurationAttributes); + + boolean updateGroup(Object group, Map configurationAttributes); + + boolean postUpdateGroup(Object group, Map configurationAttributes); + + boolean deleteGroup(Object group, Map configurationAttributes); + + boolean postDeleteGroup(Object group, Map configurationAttributes); + + boolean getUser(Object user, Map configurationAttributes); + + boolean getGroup(Object group, Map configurationAttributes); + + boolean postSearchUsers(Object results, Map configurationAttributes); + + boolean postSearchGroups(Object results, Map configurationAttributes); + + Response manageResourceOperation(Object context, Object entity, Object payload, Map configurationAttributes); + + Response manageSearchOperation(Object context, Object searchRequest, Map configurationAttributes); + +} diff --git a/oxService/src/main/java/org/gluu/model/custom/script/type/scope/DummyDynamicScopeType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/scope/DummyDynamicScopeType.java similarity index 83% rename from oxService/src/main/java/org/gluu/model/custom/script/type/scope/DummyDynamicScopeType.java rename to core-script/src/main/java/org/gluu/model/custom/script/type/scope/DummyDynamicScopeType.java index 63b1fefd4..d5ee78288 100644 --- a/oxService/src/main/java/org/gluu/model/custom/script/type/scope/DummyDynamicScopeType.java +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/scope/DummyDynamicScopeType.java @@ -8,7 +8,7 @@ import java.util.Map; import org.gluu.model.SimpleCustomProperty; - +import org.gluu.model.custom.script.model.CustomScript; /** * Dummy implementation of interface DynamicScopeType * @@ -20,7 +20,10 @@ public class DummyDynamicScopeType implements DynamicScopeType { public boolean init(Map configurationAttributes) { return true; } - + @Override + public boolean init(CustomScript customScript, Map configurationAttributes) { + return true; + } @Override public boolean destroy(Map configurationAttributes) { return true; diff --git a/oxService/src/main/java/org/gluu/model/custom/script/type/scope/DynamicScopeType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/scope/DynamicScopeType.java similarity index 100% rename from oxService/src/main/java/org/gluu/model/custom/script/type/scope/DynamicScopeType.java rename to core-script/src/main/java/org/gluu/model/custom/script/type/scope/DynamicScopeType.java diff --git a/oxService/src/main/java/org/gluu/model/custom/script/type/session/ApplicationSessionType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/session/ApplicationSessionType.java similarity index 95% rename from oxService/src/main/java/org/gluu/model/custom/script/type/session/ApplicationSessionType.java rename to core-script/src/main/java/org/gluu/model/custom/script/type/session/ApplicationSessionType.java index 796c71ce9..e5c303bfb 100644 --- a/oxService/src/main/java/org/gluu/model/custom/script/type/session/ApplicationSessionType.java +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/session/ApplicationSessionType.java @@ -18,6 +18,8 @@ public interface ApplicationSessionType extends BaseExternalType { boolean startSession(Object httpRequest, Object sessionState, Map configurationAttributes); + boolean endSession(Object httpRequest, Object sessionState, Map configurationAttributes); + void onEvent(Object event); } diff --git a/oxService/src/main/java/org/gluu/model/custom/script/type/session/DummyApplicationSessionType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/session/DummyApplicationSessionType.java similarity index 81% rename from oxService/src/main/java/org/gluu/model/custom/script/type/session/DummyApplicationSessionType.java rename to core-script/src/main/java/org/gluu/model/custom/script/type/session/DummyApplicationSessionType.java index 261864dc0..b98493078 100644 --- a/oxService/src/main/java/org/gluu/model/custom/script/type/session/DummyApplicationSessionType.java +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/session/DummyApplicationSessionType.java @@ -4,10 +4,10 @@ * Copyright (c) 2014, Gluu */ package org.gluu.model.custom.script.type.session; - import java.util.Map; import org.gluu.model.SimpleCustomProperty; +import org.gluu.model.custom.script.model.CustomScript; /** * Dummy implementation of interface ApplicationSessionType @@ -20,7 +20,10 @@ public class DummyApplicationSessionType implements ApplicationSessionType { public boolean init(Map configurationAttributes) { return true; } - + @Override + public boolean init(CustomScript customScript, Map configurationAttributes) { + return true; + } @Override public boolean destroy(Map configurationAttributes) { return true; @@ -41,4 +44,7 @@ public boolean endSession(Object httpRequest, Object authorizationGrant, Map configurationAttributes) { + return true; + } + + @Override + public boolean init(Map configurationAttributes) { + return true; + } + + @Override + public boolean destroy(Map configurationAttributes) { + return true; + } + + @Override + public int getApiVersion() { + return 0; + } +} diff --git a/core-script/src/main/java/org/gluu/model/custom/script/type/spontaneous/SpontaneousScopeType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/spontaneous/SpontaneousScopeType.java new file mode 100644 index 000000000..89a703318 --- /dev/null +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/spontaneous/SpontaneousScopeType.java @@ -0,0 +1,8 @@ +package org.gluu.model.custom.script.type.spontaneous; + +import org.gluu.model.custom.script.type.BaseExternalType; + +public interface SpontaneousScopeType extends BaseExternalType { + + void manipulateScopes(Object context); +} diff --git a/core-script/src/main/java/org/gluu/model/custom/script/type/token/DummyUpdateTokenType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/token/DummyUpdateTokenType.java new file mode 100644 index 000000000..a165317c0 --- /dev/null +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/token/DummyUpdateTokenType.java @@ -0,0 +1,69 @@ +/* + * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Gluu + */ + +package org.gluu.model.custom.script.type.token; + +import org.gluu.model.SimpleCustomProperty; +import org.gluu.model.custom.script.model.CustomScript; + +import java.util.Map; + +/** + * @author Yuriy Movchan + */ +public class DummyUpdateTokenType implements UpdateTokenType { + + @Override + public boolean init(Map configurationAttributes) { + return true; + } + + @Override + public boolean init(CustomScript customScript, Map configurationAttributes) { + return true; + } + + @Override + public boolean destroy(Map configurationAttributes) { + return true; + } + + @Override + public int getApiVersion() { + return 1; + } + + @Override + public boolean modifyIdToken(Object jwr, Object tokenContext) { + return false; + } + + @Override + public boolean modifyRefreshToken(Object refreshToken, Object tokenContext) { + return false; + } + + @Override + public boolean modifyAccessToken(Object accessToken, Object tokenContext) { + return false; + } + + @Override + public int getRefreshTokenLifetimeInSeconds(Object tokenContext) { + return 0; + } + + @Override + public int getIdTokenLifetimeInSeconds(Object context) { + return 0; + } + + @Override + public int getAccessTokenLifetimeInSeconds(Object context) { + return 0; + } + +} diff --git a/core-script/src/main/java/org/gluu/model/custom/script/type/token/UpdateTokenType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/token/UpdateTokenType.java new file mode 100644 index 000000000..dafae0843 --- /dev/null +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/token/UpdateTokenType.java @@ -0,0 +1,27 @@ +/* + * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Gluu + */ + +package org.gluu.model.custom.script.type.token; + +import org.gluu.model.custom.script.type.BaseExternalType; + +/** + * @author Yuriy Movchan + */ +public interface UpdateTokenType extends BaseExternalType { + + boolean modifyIdToken(Object jsonWebResponse, Object tokenContext); + + boolean modifyRefreshToken(Object refreshToken, Object tokenContext); + + boolean modifyAccessToken(Object accessToken, Object tokenContext); + + int getRefreshTokenLifetimeInSeconds(Object tokenContext); + + int getIdTokenLifetimeInSeconds(Object context); + + int getAccessTokenLifetimeInSeconds(Object context); +} diff --git a/oxService/src/main/java/org/gluu/model/custom/script/type/uma/UmaClaimsGatheringType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/uma/UmaClaimsGatheringType.java similarity index 100% rename from oxService/src/main/java/org/gluu/model/custom/script/type/uma/UmaClaimsGatheringType.java rename to core-script/src/main/java/org/gluu/model/custom/script/type/uma/UmaClaimsGatheringType.java diff --git a/oxService/src/main/java/org/gluu/model/custom/script/type/uma/UmaDummyClaimsGatheringType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/uma/UmaDummyClaimsGatheringType.java similarity index 83% rename from oxService/src/main/java/org/gluu/model/custom/script/type/uma/UmaDummyClaimsGatheringType.java rename to core-script/src/main/java/org/gluu/model/custom/script/type/uma/UmaDummyClaimsGatheringType.java index 1de8936ae..4fc9cb562 100644 --- a/oxService/src/main/java/org/gluu/model/custom/script/type/uma/UmaDummyClaimsGatheringType.java +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/uma/UmaDummyClaimsGatheringType.java @@ -3,7 +3,7 @@ import java.util.Map; import org.gluu.model.SimpleCustomProperty; - +import org.gluu.model.custom.script.model.CustomScript; /** * @author yuriyz on 06/16/2017. */ @@ -38,7 +38,10 @@ public String getPageForStep(int step, Object gatheringContext) { public boolean init(Map configurationAttributes) { return true; } - + @Override + public boolean init(CustomScript customScript, Map configurationAttributes) { + return true; + } @Override public boolean destroy(Map configurationAttributes) { return true; diff --git a/core-script/src/main/java/org/gluu/model/custom/script/type/uma/UmaDummyRptClaimsType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/uma/UmaDummyRptClaimsType.java new file mode 100644 index 000000000..42ed90b3b --- /dev/null +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/uma/UmaDummyRptClaimsType.java @@ -0,0 +1,37 @@ +package org.gluu.model.custom.script.type.uma; + +import org.gluu.model.SimpleCustomProperty; +import org.gluu.model.custom.script.model.CustomScript; + +import java.util.Map; + +/** + * @author Yuriy Zabrovarnyy + */ +public class UmaDummyRptClaimsType implements UmaRptClaimsType { + + @Override + public boolean modify(Object rptAsJsonObject, Object context) { + return false; + } + + @Override + public boolean init(Map configurationAttributes) { + return true; + } + + @Override + public boolean init(CustomScript customScript, Map configurationAttributes) { + return true; + } + + @Override + public boolean destroy(Map configurationAttributes) { + return true; + } + + @Override + public int getApiVersion() { + return 1; + } +} diff --git a/oxService/src/main/java/org/gluu/model/custom/script/type/uma/UmaDummyRptPolicyType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/uma/UmaDummyRptPolicyType.java similarity index 82% rename from oxService/src/main/java/org/gluu/model/custom/script/type/uma/UmaDummyRptPolicyType.java rename to core-script/src/main/java/org/gluu/model/custom/script/type/uma/UmaDummyRptPolicyType.java index 2c5c1f0cf..debabd0dd 100644 --- a/oxService/src/main/java/org/gluu/model/custom/script/type/uma/UmaDummyRptPolicyType.java +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/uma/UmaDummyRptPolicyType.java @@ -5,8 +5,8 @@ import java.util.Map; import org.gluu.model.SimpleCustomProperty; +import org.gluu.model.custom.script.model.CustomScript; import org.gluu.model.uma.ClaimDefinition; - /** * @author yuriyz on 05/30/2017. */ @@ -16,7 +16,10 @@ public class UmaDummyRptPolicyType implements UmaRptPolicyType { public boolean init(Map configurationAttributes) { return true; } - + @Override + public boolean init(CustomScript customScript, Map configurationAttributes) { + return true; + } @Override public boolean destroy(Map configurationAttributes) { return true; diff --git a/core-script/src/main/java/org/gluu/model/custom/script/type/uma/UmaRptClaimsType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/uma/UmaRptClaimsType.java new file mode 100644 index 000000000..0ff56ca73 --- /dev/null +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/uma/UmaRptClaimsType.java @@ -0,0 +1,11 @@ +package org.gluu.model.custom.script.type.uma; + +import org.gluu.model.custom.script.type.BaseExternalType; + +/** + * @author Yuriy Zabrovarnyy + */ +public interface UmaRptClaimsType extends BaseExternalType { + + boolean modify(Object rptAsJsonObject, Object context); +} diff --git a/oxService/src/main/java/org/gluu/model/custom/script/type/uma/UmaRptPolicyType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/uma/UmaRptPolicyType.java similarity index 100% rename from oxService/src/main/java/org/gluu/model/custom/script/type/uma/UmaRptPolicyType.java rename to core-script/src/main/java/org/gluu/model/custom/script/type/uma/UmaRptPolicyType.java diff --git a/oxService/src/main/java/org/gluu/model/custom/script/type/user/CacheRefreshType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/user/CacheRefreshType.java similarity index 88% rename from oxService/src/main/java/org/gluu/model/custom/script/type/user/CacheRefreshType.java rename to core-script/src/main/java/org/gluu/model/custom/script/type/user/CacheRefreshType.java index 878ee8ccc..6ff5108f2 100644 --- a/oxService/src/main/java/org/gluu/model/custom/script/type/user/CacheRefreshType.java +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/user/CacheRefreshType.java @@ -24,4 +24,6 @@ public interface CacheRefreshType extends BaseExternalType { public boolean updateUser(Object person, Map configurationAttributes); + public boolean updateSourceUser(Object person, Map configurationAttributes); + } diff --git a/oxService/src/main/java/org/gluu/model/custom/script/type/user/DummyCacheRefreshType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/user/DummyCacheRefreshType.java similarity index 76% rename from oxService/src/main/java/org/gluu/model/custom/script/type/user/DummyCacheRefreshType.java rename to core-script/src/main/java/org/gluu/model/custom/script/type/user/DummyCacheRefreshType.java index a817b2511..a89966b21 100644 --- a/oxService/src/main/java/org/gluu/model/custom/script/type/user/DummyCacheRefreshType.java +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/user/DummyCacheRefreshType.java @@ -8,8 +8,8 @@ import java.util.Map; import org.gluu.model.SimpleCustomProperty; +import org.gluu.model.custom.script.model.CustomScript; import org.gluu.model.custom.script.model.bind.BindCredentials; - /** * Dummy implementation of interface CacheRefreshType * @@ -21,7 +21,10 @@ public class DummyCacheRefreshType implements CacheRefreshType { public boolean init(Map configurationAttributes) { return true; } - + @Override + public boolean init(CustomScript customScript, Map configurationAttributes) { + return true; + } @Override public boolean destroy(Map configurationAttributes) { return true; @@ -29,7 +32,7 @@ public boolean destroy(Map configurationAttributes @Override public int getApiVersion() { - return 2; + return 3; } @Override @@ -37,6 +40,11 @@ public boolean updateUser(Object person, Map confi return false; } + @Override + public boolean updateSourceUser(Object person, Map configurationAttributes) { + return false; + } + @Override public BindCredentials getBindCredentials(String configId, Map configurationAttributes) { return null; diff --git a/oxService/src/main/java/org/gluu/model/custom/script/type/user/DummyUpdateUserType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/user/DummyUpdateUserType.java similarity index 89% rename from oxService/src/main/java/org/gluu/model/custom/script/type/user/DummyUpdateUserType.java rename to core-script/src/main/java/org/gluu/model/custom/script/type/user/DummyUpdateUserType.java index a73dde8a2..69a340d02 100644 --- a/oxService/src/main/java/org/gluu/model/custom/script/type/user/DummyUpdateUserType.java +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/user/DummyUpdateUserType.java @@ -8,7 +8,7 @@ import java.util.Map; import org.gluu.model.SimpleCustomProperty; - +import org.gluu.model.custom.script.model.CustomScript; /** * Dummy implementation of interface UpdateUserType * @@ -21,7 +21,10 @@ public class DummyUpdateUserType implements UpdateUserType { public boolean init(Map configurationAttributes) { return true; } - + @Override + public boolean init(CustomScript customScript, Map configurationAttributes) { + return true; + } @Override public boolean destroy(Map configurationAttributes) { return true; diff --git a/oxService/src/main/java/org/gluu/model/custom/script/type/user/DummyUserRegistrationType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/user/DummyUserRegistrationType.java similarity index 88% rename from oxService/src/main/java/org/gluu/model/custom/script/type/user/DummyUserRegistrationType.java rename to core-script/src/main/java/org/gluu/model/custom/script/type/user/DummyUserRegistrationType.java index 8c903ec55..536f40d1c 100644 --- a/oxService/src/main/java/org/gluu/model/custom/script/type/user/DummyUserRegistrationType.java +++ b/core-script/src/main/java/org/gluu/model/custom/script/type/user/DummyUserRegistrationType.java @@ -8,7 +8,7 @@ import java.util.Map; import org.gluu.model.SimpleCustomProperty; - +import org.gluu.model.custom.script.model.CustomScript; /** * Dummy implementation of interface UserRegistrationType * @@ -20,7 +20,10 @@ public class DummyUserRegistrationType implements UserRegistrationType { public boolean init(Map configurationAttributes) { return true; } - + @Override + public boolean init(CustomScript customScript, Map configurationAttributes) { + return true; + } @Override public boolean destroy(Map configurationAttributes) { return true; diff --git a/oxService/src/main/java/org/gluu/model/custom/script/type/user/UpdateUserType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/user/UpdateUserType.java similarity index 100% rename from oxService/src/main/java/org/gluu/model/custom/script/type/user/UpdateUserType.java rename to core-script/src/main/java/org/gluu/model/custom/script/type/user/UpdateUserType.java diff --git a/oxService/src/main/java/org/gluu/model/custom/script/type/user/UserRegistrationType.java b/core-script/src/main/java/org/gluu/model/custom/script/type/user/UserRegistrationType.java similarity index 100% rename from oxService/src/main/java/org/gluu/model/custom/script/type/user/UserRegistrationType.java rename to core-script/src/main/java/org/gluu/model/custom/script/type/user/UserRegistrationType.java diff --git a/oxService/src/main/java/org/gluu/service/PythonService.java b/core-script/src/main/java/org/gluu/service/PythonService.java similarity index 91% rename from oxService/src/main/java/org/gluu/service/PythonService.java rename to core-script/src/main/java/org/gluu/service/PythonService.java index 908234707..ce13fd20b 100644 --- a/oxService/src/main/java/org/gluu/service/PythonService.java +++ b/core-script/src/main/java/org/gluu/service/PythonService.java @@ -19,7 +19,6 @@ import javax.annotation.PreDestroy; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; -import javax.inject.Named; import org.gluu.exception.PythonException; import org.gluu.persist.reflect.util.ReflectHelper; @@ -28,6 +27,7 @@ import org.python.core.PyObject; import org.python.util.PythonInterpreter; import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Provides operations with python module @@ -35,7 +35,6 @@ * @author Yuriy Movchan Date: 08.21.2012 */ @ApplicationScoped -@Named public class PythonService implements Serializable { private static final long serialVersionUID = 3398422090669045605L; @@ -58,15 +57,21 @@ public void init() { } } + public void configure() { + this.log = LoggerFactory.getLogger(PythonService.class); + } + /* * Initialize singleton instance during startup */ public boolean initPythonInterpreter(String pythonModulesDir) { boolean result = false; - if (isInitInterpreter()) { + String pythonHome = getPythonHome(); + log.info("Initializing PythonService with Jython: '{}'", pythonHome); + if (StringHelper.isNotEmpty(pythonHome)) { try { - PythonInterpreter.initialize(getPreProperties(), getPostProperties(pythonModulesDir), null); + PythonInterpreter.initialize(getPreProperties(), getPostProperties(pythonModulesDir, pythonHome), null); this.pythonInterpreter = new PythonInterpreter(); initPythonInterpreter(this.pythonInterpreter); @@ -77,6 +82,8 @@ public boolean initPythonInterpreter(String pythonModulesDir) { } catch (Exception ex) { log.error("Failed to initialize PythonInterpreter correctly", ex); } + } else { + log.error("Failed to initialize PythonService. Jython location is not defined!"); } this.interpereterReady = result; @@ -117,16 +124,13 @@ private Properties getPreProperties() { return clonedProps; } - private Properties getPostProperties(String pythonModulesDir) { + private Properties getPostProperties(String pythonModulesDir, String pythonHome) { Properties props = getPreProperties(); String catalinaTmpFolder = System.getProperty("java.io.tmpdir") + File.separator + "python" + File.separator + "cachedir"; props.setProperty("python.cachedir", catalinaTmpFolder); - String pythonHome = System.getenv("PYTHON_HOME"); - if (StringHelper.isNotEmpty(pythonHome)) { - props.setProperty("python.home", pythonHome); - } + props.setProperty("python.home", pythonHome); // Register custom python modules if (StringHelper.isNotEmpty(pythonModulesDir)) { @@ -139,15 +143,14 @@ private Properties getPostProperties(String pythonModulesDir) { return props; } - private boolean isInitInterpreter() { - String pythonHome = System.getenv("PYTHON_HOME"); + private String getPythonHome() { + String pythonHome = System.getenv("PYTHON_HOME"); if (StringHelper.isNotEmpty(pythonHome)) { - System.setProperty("python.home", pythonHome); + return pythonHome; } - String pythonHomeProperty = System.getProperty("python.home"); - return StringHelper.isNotEmpty(pythonHomeProperty); - } + return System.getProperty("python.home"); + } public T loadPythonScript(String scriptName, String scriptPythonType, Class scriptJavaType, PyObject[] constructorArgs) throws PythonException { diff --git a/oxService/src/main/java/org/gluu/service/cdi/event/UpdateScriptEvent.java b/core-script/src/main/java/org/gluu/service/cdi/event/UpdateScriptEvent.java similarity index 100% rename from oxService/src/main/java/org/gluu/service/cdi/event/UpdateScriptEvent.java rename to core-script/src/main/java/org/gluu/service/cdi/event/UpdateScriptEvent.java diff --git a/oxService/src/main/java/org/gluu/service/custom/inject/ReloadScript.java b/core-script/src/main/java/org/gluu/service/custom/inject/ReloadScript.java similarity index 100% rename from oxService/src/main/java/org/gluu/service/custom/inject/ReloadScript.java rename to core-script/src/main/java/org/gluu/service/custom/inject/ReloadScript.java diff --git a/core-script/src/main/java/org/gluu/service/custom/script/AbstractCustomScriptService.java b/core-script/src/main/java/org/gluu/service/custom/script/AbstractCustomScriptService.java new file mode 100644 index 000000000..47a8d7c52 --- /dev/null +++ b/core-script/src/main/java/org/gluu/service/custom/script/AbstractCustomScriptService.java @@ -0,0 +1,211 @@ +/* + * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2014, Gluu + */ +package org.gluu.service.custom.script; + +import com.google.common.base.Optional; +import org.gluu.model.custom.script.CustomScriptType; +import org.gluu.model.custom.script.model.CustomScript; +import org.gluu.persist.PersistenceEntryManager; +import org.gluu.search.filter.Filter; +import org.gluu.util.OxConstants; +import org.slf4j.Logger; + +import javax.inject.Inject; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * Operations with custom scripts + * + * @author Yuriy Movchan Date: 12/03/2014 + * @author Mougang T.Gasmyr + */ +public abstract class AbstractCustomScriptService implements Serializable { + + private static final long serialVersionUID = -6187179012715072064L; + + @Inject + protected Logger log; + + @Inject + protected PersistenceEntryManager persistenceEntryManager; + + public void add(CustomScript customScript) { + persistenceEntryManager.persist(customScript); + } + + public void update(CustomScript customScript) { + persistenceEntryManager.merge(customScript); + } + + public void remove(CustomScript customScript) { + persistenceEntryManager.remove(customScript); + } + + public CustomScript getCustomScriptByDn(String customScriptDn, String... returnAttributes) { + return persistenceEntryManager.find(customScriptDn, CustomScript.class, returnAttributes); + } + + public CustomScript getCustomScriptByDn(Class customScriptType, String customScriptDn) { + return (CustomScript) persistenceEntryManager.find(customScriptType, customScriptDn); + } + + public Optional getCustomScriptByINum(String baseDn, String inum, String... returnAttributes) { + + final List customScriptTypeFilters = new ArrayList(); + + final Filter customScriptTypeFilter = Filter.createEqualityFilter("inum", inum); + customScriptTypeFilters.add(customScriptTypeFilter); + + final Filter filter = Filter.createORFilter(customScriptTypeFilters); + + final List result = persistenceEntryManager.findEntries(baseDn, CustomScript.class, filter, returnAttributes); + + if (result.isEmpty()) { + + return Optional.absent(); + } + + return Optional.of(result.get(0)); + } + + + public List findAllCustomScripts(String[] returnAttributes) { + String baseDn = baseDn(); + + List result = persistenceEntryManager.findEntries(baseDn, CustomScript.class, null, returnAttributes); + + return result; + } + + public List findCustomScripts(List customScriptTypes, String... returnAttributes) { + String baseDn = baseDn(); + + if ((customScriptTypes == null) || (customScriptTypes.size() == 0)) { + return findAllCustomScripts(returnAttributes); + } + + List customScriptTypeFilters = new ArrayList(); + for (CustomScriptType customScriptType : customScriptTypes) { + Filter customScriptTypeFilter = Filter.createEqualityFilter("oxScriptType", customScriptType.getValue()); + customScriptTypeFilters.add(customScriptTypeFilter); + } + + Filter filter = Filter.createORFilter(customScriptTypeFilters); + + List result = persistenceEntryManager.findEntries(baseDn, CustomScript.class, filter, returnAttributes); + + return result; + } + + public CustomScript getScriptByInum(String inum) { + return persistenceEntryManager.find(CustomScript.class, buildDn(inum)); + } + + public List findCustomAuthScripts(String pattern, int sizeLimit) { + String[] targetArray = new String[]{pattern}; + Filter descriptionFilter = Filter.createSubstringFilter(OxConstants.DESCRIPTION, null, targetArray, null); + Filter scriptTypeFilter = Filter.createEqualityFilter(OxConstants.SCRIPT_TYPE, + CustomScriptType.PERSON_AUTHENTICATION); + Filter displayNameFilter = Filter.createSubstringFilter(OxConstants.DISPLAY_NAME, null, targetArray, null); + Filter searchFilter = Filter.createORFilter(descriptionFilter, displayNameFilter); + + return persistenceEntryManager.findEntries(baseDn(), CustomScript.class, + Filter.createANDFilter(searchFilter, scriptTypeFilter), sizeLimit); + } + + public List findCustomAuthScripts(int sizeLimit) { + Filter searchFilter = Filter.createEqualityFilter(OxConstants.SCRIPT_TYPE, + CustomScriptType.PERSON_AUTHENTICATION.getValue()); + + return persistenceEntryManager.findEntries(baseDn(), CustomScript.class, searchFilter, + sizeLimit); + } + + + public CustomScript getScriptByDisplayName(String name) { + Filter searchFilter = Filter.createEqualityFilter("displayName", + name); + List result=persistenceEntryManager.findEntries(baseDn(), CustomScript.class, searchFilter, + 1); + if(result!=null && !result.isEmpty()){ + return result.get(0); + } + return null; + } + public int getScriptLevel(CustomScript customScript) { + if(customScript!=null){ + return customScript.getLevel(); + } + return -2; + } + + public List findOtherCustomScripts(String pattern, int sizeLimit) { + String[] targetArray = new String[]{pattern}; + Filter descriptionFilter = Filter.createSubstringFilter(OxConstants.DESCRIPTION, null, targetArray, null); + Filter scriptTypeFilter = Filter.createNOTFilter( + Filter.createEqualityFilter(OxConstants.SCRIPT_TYPE, CustomScriptType.PERSON_AUTHENTICATION)); + Filter displayNameFilter = Filter.createSubstringFilter(OxConstants.DISPLAY_NAME, null, targetArray, null); + Filter searchFilter = Filter.createORFilter(descriptionFilter, displayNameFilter); + + return persistenceEntryManager.findEntries(baseDn(), CustomScript.class, + Filter.createANDFilter(searchFilter, scriptTypeFilter), sizeLimit); + } + + public List findScriptByType(CustomScriptType type, int sizeLimit) { + Filter searchFilter = Filter.createEqualityFilter(OxConstants.SCRIPT_TYPE, type); + + return persistenceEntryManager.findEntries(baseDn(), CustomScript.class, searchFilter, + sizeLimit); + } + + public List findScriptByType(CustomScriptType type) { + Filter searchFilter = Filter.createEqualityFilter(OxConstants.SCRIPT_TYPE, type); + + return persistenceEntryManager.findEntries(baseDn(), CustomScript.class, searchFilter, null); + } + + public List findScriptByPatternAndType(String pattern, CustomScriptType type, int sizeLimit) { + String[] targetArray = new String[]{pattern}; + Filter descriptionFilter = Filter.createSubstringFilter(OxConstants.DESCRIPTION, null, targetArray, null); + Filter displayNameFilter = Filter.createSubstringFilter(OxConstants.DISPLAY_NAME, null, targetArray, null); + Filter searchFilter = Filter.createORFilter(descriptionFilter, displayNameFilter); + Filter typeFilter = Filter.createEqualityFilter(OxConstants.SCRIPT_TYPE, type); + + return persistenceEntryManager.findEntries(baseDn(), CustomScript.class, + Filter.createANDFilter(searchFilter, typeFilter), sizeLimit); + } + + public List findScriptByPatternAndType(String pattern, CustomScriptType type) { + String[] targetArray = new String[]{pattern}; + Filter descriptionFilter = Filter.createSubstringFilter(OxConstants.DESCRIPTION, null, targetArray, null); + Filter displayNameFilter = Filter.createSubstringFilter(OxConstants.DISPLAY_NAME, null, targetArray, null); + Filter searchFilter = Filter.createORFilter(descriptionFilter, displayNameFilter); + Filter typeFilter = Filter.createEqualityFilter(OxConstants.SCRIPT_TYPE, type); + + return persistenceEntryManager.findEntries(baseDn(), CustomScript.class, + Filter.createANDFilter(searchFilter, typeFilter), null); + } + + public List findOtherCustomScripts(int sizeLimit) { + Filter searchFilter = Filter.createNOTFilter( + Filter.createEqualityFilter(OxConstants.SCRIPT_TYPE, CustomScriptType.PERSON_AUTHENTICATION)); + + return persistenceEntryManager.findEntries(baseDn(), CustomScript.class, searchFilter, + sizeLimit); + } + + public String buildDn(String customScriptId) { + final StringBuilder dn = new StringBuilder(); + dn.append(String.format("inum=%s,", customScriptId)); + dn.append(baseDn()); + return dn.toString(); + } + + public abstract String baseDn(); + +} diff --git a/oxService/src/main/java/org/gluu/service/custom/script/CustomScriptManager.java b/core-script/src/main/java/org/gluu/service/custom/script/CustomScriptManager.java similarity index 85% rename from oxService/src/main/java/org/gluu/service/custom/script/CustomScriptManager.java rename to core-script/src/main/java/org/gluu/service/custom/script/CustomScriptManager.java index 3c93ee0ed..593d025f7 100644 --- a/oxService/src/main/java/org/gluu/service/custom/script/CustomScriptManager.java +++ b/core-script/src/main/java/org/gluu/service/custom/script/CustomScriptManager.java @@ -24,6 +24,7 @@ import javax.enterprise.context.BeforeDestroyed; import javax.enterprise.event.Event; import javax.enterprise.event.Observes; +import javax.enterprise.inject.Instance; import javax.inject.Inject; import javax.servlet.ServletContext; @@ -62,7 +63,7 @@ public class CustomScriptManager implements Serializable { private static final long serialVersionUID = -4225890597520443390L; public static final String CUSTOM_SCRIPT_MODIFIED_EVENT_TYPE = "customScriptModifiedEvent"; - private static final int DEFAULT_INTERVAL = 30; // 30 seconds + public static final int DEFAULT_INTERVAL = 30; // 30 seconds public static final String[] CUSTOM_SCRIPT_CHECK_ATTRIBUTES = { "dn", "inum", "oxRevision", "oxScriptType", "oxModuleProperty", "oxEnabled" }; @@ -74,7 +75,7 @@ public class CustomScriptManager implements Serializable { private Event timerEvent; @Inject - private PythonService pythonService; + protected PythonService pythonService; @Inject protected AbstractCustomScriptService customScriptService; @@ -83,6 +84,9 @@ public class CustomScriptManager implements Serializable { @ReloadScript private Event event; + @Inject + private Instance externalScriptServiceInstance; + protected List supportedCustomScriptTypes; private Map customScriptConfigurations; @@ -95,18 +99,22 @@ public class CustomScriptManager implements Serializable { public void initTimer(List supportedCustomScriptTypes) { this.supportedCustomScriptTypes = supportedCustomScriptTypes; - this.isActive = new AtomicBoolean(false); - this.lastFinishedTime = System.currentTimeMillis(); + configure(); final int delay = 30; final int interval = DEFAULT_INTERVAL; - reload(); + reload(true); timerEvent.fire(new TimerEvent(new TimerSchedule(delay, interval), new UpdateScriptEvent(), Scheduled.Literal.INSTANCE)); } + protected void configure() { + this.isActive = new AtomicBoolean(false); + this.lastFinishedTime = System.currentTimeMillis(); + } + public void reloadTimerEvent(@Observes @Scheduled UpdateScriptEvent updateScriptEvent) { if (this.isActive.get()) { return; @@ -117,7 +125,7 @@ public void reloadTimerEvent(@Observes @Scheduled UpdateScriptEvent updateScript } try { - reload(); + reload(false); } catch (Throwable ex) { log.error("Exception happened while reloading custom scripts configuration", ex); } finally { @@ -140,18 +148,35 @@ public void destroy(@BeforeDestroyed(ApplicationScoped.class) ServletContext ini } } - private void reload() { + private void reload(boolean syncUpdate) { boolean modified = reloadImpl(); if (modified) { + updateScriptServices(syncUpdate); + } + } + + protected void updateScriptServices(boolean syncUpdate) { + if (syncUpdate) { + for (ExternalScriptService externalScriptService : externalScriptServiceInstance) { + if (supportedCustomScriptTypes.contains(externalScriptService.getCustomScriptType())) { + externalScriptService.reload(CUSTOM_SCRIPT_MODIFIED_EVENT_TYPE); + } + } + } else { event.fire(CUSTOM_SCRIPT_MODIFIED_EVENT_TYPE); } } private boolean reloadImpl() { // Load current script revisions - List customScripts = customScriptService.findCustomScripts(supportedCustomScriptTypes, - CUSTOM_SCRIPT_CHECK_ATTRIBUTES); + List customScripts; + if (supportedCustomScriptTypes.isEmpty()) { + customScripts = new ArrayList(); + } else { + customScripts = customScriptService.findCustomScripts(supportedCustomScriptTypes, + CUSTOM_SCRIPT_CHECK_ATTRIBUTES); + } // Store updated external authenticator configurations ReloadResult reloadResult = reloadCustomScriptConfigurations(this.customScriptConfigurations, customScripts); @@ -208,7 +233,7 @@ private ReloadResult reloadCustomScriptConfigurations( // reload script automatically after changing location_type long fileModifiactionTime = getFileModificationTime(newCustomScript.getLocationPath()); - newCustomScript.setRevision(fileModifiactionTime); + newCustomScript.setRevision(newCustomScript.getRevision() + fileModifiactionTime); } String newSupportedCustomScriptInum = StringHelper.toLowerCase(newCustomScript.getInum()); @@ -216,8 +241,8 @@ private ReloadResult reloadCustomScriptConfigurations( CustomScriptConfiguration prevCustomScriptConfiguration = newCustomScriptConfigurations .get(newSupportedCustomScriptInum); - if ((prevCustomScriptConfiguration == null) || (prevCustomScriptConfiguration.getCustomScript() - .getRevision() != newCustomScript.getRevision())) { + if (prevCustomScriptConfiguration == null || prevCustomScriptConfiguration.getCustomScript() + .getRevision() != newCustomScript.getRevision()) { // Destroy old version properly before creating new one if (prevCustomScriptConfiguration != null) { destroyCustomScript(prevCustomScriptConfiguration); @@ -245,7 +270,7 @@ private ReloadResult reloadCustomScriptConfigurations( // Replace script revision with file modification time. This should allow to // reload script automatically after changing location_type long fileModifiactionTime = getFileModificationTime(loadedCustomScript.getLocationPath()); - loadedCustomScript.setRevision(fileModifiactionTime); + loadedCustomScript.setRevision(loadedCustomScript.getRevision() + fileModifiactionTime); if (fileModifiactionTime != 0) { String scriptFromFile = loadFromFile(loadedCustomScript.getLocationPath()); @@ -343,7 +368,9 @@ private Map> groupCustomScript CustomScriptType customScriptType = customScriptConfiguration.getCustomScript().getScriptType(); List customConfigurationsByScriptType = newCustomScriptConfigurationsByScriptType .get(customScriptType); - customConfigurationsByScriptType.add(customScriptConfiguration); + if (customConfigurationsByScriptType != null) { + customConfigurationsByScriptType.add(customScriptConfiguration); + } } return newCustomScriptConfigurationsByScriptType; @@ -401,7 +428,21 @@ public BaseExternalType createExternalTypeFromStringWithPythonException(CustomSc boolean initialized = false; try { - initialized = externalType.init(configurationAttributes); + // Workaround to allow load all required class in init method needed for proper script work + // At the end we restore ContextClassLoader + // More details: https://github.com/JanssenProject/jans/issues/5116 + ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); + try { + if (externalType.getApiVersion() > 10) { + initialized = externalType.init(customScript, configurationAttributes); + } else { + initialized = externalType.init(configurationAttributes); + log.warn(" Update the script's init method to init(self, customScript, configurationAttributes)", customScript.getName()); + } + } finally { + Thread.currentThread().setContextClassLoader(oldClassLoader); + } } catch (Exception ex) { log.error("Failed to initialize custom script: '{}'", ex, customScript.getName()); } @@ -495,8 +536,12 @@ public CustomScriptConfiguration getCustomScriptConfigurationByInum(String inum) public List getCustomScriptConfigurationsByScriptType( CustomScriptType customScriptType) { - return new ArrayList( - this.customScriptConfigurationsByScriptType.get(customScriptType)); + List tmpCustomScriptConfigurationsByScriptType = this.customScriptConfigurationsByScriptType + .get(customScriptType); + if (tmpCustomScriptConfigurationsByScriptType == null) { + tmpCustomScriptConfigurationsByScriptType = new ArrayList(0); + } + return new ArrayList(tmpCustomScriptConfigurationsByScriptType); } public List getCustomScriptConfigurations() { @@ -507,4 +552,8 @@ public List getSupportedCustomScriptTypes() { return supportedCustomScriptTypes; } + public boolean isSupportedType(CustomScriptType customScriptType) { + return supportedCustomScriptTypes.contains(customScriptType); + } + } diff --git a/oxService/src/main/java/org/gluu/service/custom/script/ExternalScriptService.java b/core-script/src/main/java/org/gluu/service/custom/script/ExternalScriptService.java similarity index 77% rename from oxService/src/main/java/org/gluu/service/custom/script/ExternalScriptService.java rename to core-script/src/main/java/org/gluu/service/custom/script/ExternalScriptService.java index 203ac05c3..7d7dd39d8 100644 --- a/oxService/src/main/java/org/gluu/service/custom/script/ExternalScriptService.java +++ b/core-script/src/main/java/org/gluu/service/custom/script/ExternalScriptService.java @@ -11,6 +11,7 @@ import java.util.List; import java.util.Map; +import javax.annotation.PostConstruct; import javax.enterprise.event.Observes; import javax.inject.Inject; @@ -21,13 +22,16 @@ import org.gluu.service.custom.inject.ReloadScript; import org.gluu.util.StringHelper; import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.Lists; /** * Provides factory methods needed to create external extension * * @author Yuriy Movchan Date: 01/08/2015 */ -public class ExternalScriptService implements Serializable { +public abstract class ExternalScriptService implements Serializable { private static final long serialVersionUID = -1070021905117441202L; @@ -38,16 +42,35 @@ public class ExternalScriptService implements Serializable { protected CustomScriptManager customScriptManager; protected CustomScriptType customScriptType; + + protected boolean loaded; protected Map customScriptConfigurationsNameMap; protected List customScriptConfigurations; protected CustomScriptConfiguration defaultExternalCustomScript; + @PostConstruct + public void init() { + this.loaded = false; + } + public ExternalScriptService(CustomScriptType customScriptType) { this.customScriptType = customScriptType; } + /** + * Method for standalone usage + */ + public void configure(StandaloneCustomScriptManager customScriptManager) { + this.customScriptManager = customScriptManager; + this.log = LoggerFactory.getLogger(ExternalScriptService.class); + } + public void reload(@Observes @ReloadScript String event) { + // Skip reload if global script is not enabled for this application + if (!customScriptManager.isSupportedType(customScriptType)) { + return; + } // Get actual list of external configurations List newCustomScriptConfigurations = customScriptManager .getCustomScriptConfigurationsByScriptType(customScriptType); @@ -61,6 +84,8 @@ public void reload(@Observes @ReloadScript String event) { // Allow to execute additional logic reloadExternal(); + + loaded = true; } protected void addExternalConfigurations(List newCustomScriptConfigurations) { @@ -94,7 +119,7 @@ public CustomScriptConfiguration determineDefaultCustomScriptConfiguration(List< public int executeExternalGetApiVersion(CustomScriptConfiguration customScriptConfiguration) { try { - log.debug("Executing python 'getApiVersion' authenticator method"); + log.trace("Executing python 'getApiVersion' authenticator method"); BaseExternalType externalAuthenticator = (BaseExternalType) customScriptConfiguration.getExternalType(); return externalAuthenticator.getApiVersion(); } catch (Exception ex) { @@ -133,4 +158,25 @@ public List getCustomScriptConfigurations() { return this.customScriptConfigurations; } + public List getCustomScriptConfigurationsByDns(List dns) { + if (dns == null || dns.isEmpty() || customScriptConfigurations == null || customScriptConfigurations.isEmpty()) { + return Lists.newArrayList(); + } + List scripts = Lists.newArrayList(); + for (CustomScriptConfiguration script : customScriptConfigurations) { + if (dns.contains(script.getCustomScript().getDn())) { + scripts.add(script); + } + } + return scripts; + } + + public CustomScriptType getCustomScriptType() { + return customScriptType; + } + + public boolean isLoaded() { + return loaded; + } + } diff --git a/core-script/src/main/java/org/gluu/service/custom/script/StandaloneCustomScriptManager.java b/core-script/src/main/java/org/gluu/service/custom/script/StandaloneCustomScriptManager.java new file mode 100644 index 000000000..399accee6 --- /dev/null +++ b/core-script/src/main/java/org/gluu/service/custom/script/StandaloneCustomScriptManager.java @@ -0,0 +1,69 @@ +package org.gluu.service.custom.script; + +import java.util.ArrayList; +import java.util.List; + +import javax.enterprise.inject.Vetoed; + +import org.gluu.model.custom.script.CustomScriptType; +import org.gluu.persist.PersistenceEntryManager; +import org.gluu.service.PythonService; +import org.slf4j.LoggerFactory; + +/** + * Standalone custom script manager + * + * @author Yuriy Movchan Date: 06/19/2020 + */ +@Vetoed +public class StandaloneCustomScriptManager extends CustomScriptManager { + + private static final long serialVersionUID = -7212146007659551839L; + + private List externalScriptServices = new ArrayList(); + + public StandaloneCustomScriptManager(PersistenceEntryManager entryManager, String scriptsBaseDn, String pythonModulesDir) { + // Configure python service + PythonService pythonService = new PythonService(); + pythonService.configure(); + pythonService.init(); + // Initialize python interpreter + pythonService.initPythonInterpreter(pythonModulesDir); + + // Configure custom script service + StandaloneCustomScriptService standaloneCustomScriptService = new StandaloneCustomScriptService(); + standaloneCustomScriptService.configure(entryManager, scriptsBaseDn); + + this.log = LoggerFactory.getLogger(StandaloneCustomScriptManager.class); + this.supportedCustomScriptTypes = new ArrayList(); + this.pythonService = pythonService; + this.customScriptService = standaloneCustomScriptService; + } + + public void init() { + configure(); + reloadTimerEvent(null); + } + + public void destory() { + super.destroy(null); + } + + public void reload() { + reloadTimerEvent(null); + } + + public void registerExternalScriptService(ExternalScriptService externalScriptService) { + externalScriptService.configure(this); + externalScriptServices.add(externalScriptService); + supportedCustomScriptTypes.add(externalScriptService.getCustomScriptType()); + } + + @Override + public void updateScriptServices(boolean syncUpdate) { + for (ExternalScriptService externalScriptService : externalScriptServices) { + externalScriptService.reload(null); + } + } + +} diff --git a/core-script/src/main/java/org/gluu/service/custom/script/StandaloneCustomScriptService.java b/core-script/src/main/java/org/gluu/service/custom/script/StandaloneCustomScriptService.java new file mode 100644 index 000000000..4b8c266fb --- /dev/null +++ b/core-script/src/main/java/org/gluu/service/custom/script/StandaloneCustomScriptService.java @@ -0,0 +1,31 @@ +package org.gluu.service.custom.script; + +import javax.enterprise.inject.Vetoed; + +import org.gluu.persist.PersistenceEntryManager; +import org.gluu.service.PythonService; +import org.slf4j.LoggerFactory; + +/** + * Operations with custom scripts + * + * @author Yuriy Movchan Date: 06/19/2020 + */ +@Vetoed +public class StandaloneCustomScriptService extends AbstractCustomScriptService { + + private static final long serialVersionUID = -5283102477313448031L; + + private String scriptsBaseDn; + + public void configure(PersistenceEntryManager entryManager, String scriptsBaseDn) { + this.scriptsBaseDn = scriptsBaseDn; + this.log = LoggerFactory.getLogger(PythonService.class); + this.persistenceEntryManager = entryManager; + } + + public String baseDn() { + return scriptsBaseDn; + } + +} diff --git a/persistence-ldap/src/main/resources/META-INF/beans.xml b/core-script/src/main/resources/META-INF/beans.xml similarity index 100% rename from persistence-ldap/src/main/resources/META-INF/beans.xml rename to core-script/src/main/resources/META-INF/beans.xml diff --git a/core-script/src/test/java/org/gluu/service/custom/script/test/SampleIdpExternalScriptService.java b/core-script/src/test/java/org/gluu/service/custom/script/test/SampleIdpExternalScriptService.java new file mode 100644 index 000000000..b206c21c6 --- /dev/null +++ b/core-script/src/test/java/org/gluu/service/custom/script/test/SampleIdpExternalScriptService.java @@ -0,0 +1,85 @@ +package org.gluu.service.custom.script.test; + +import java.util.Map; + +import org.gluu.model.SimpleCustomProperty; +import org.gluu.model.custom.script.CustomScriptType; +import org.gluu.model.custom.script.conf.CustomScriptConfiguration; +import org.gluu.model.custom.script.type.idp.IdpType; +import org.gluu.service.custom.script.ExternalScriptService; + +/** + * External IDP script service + * + * @author Yuriy Movchan + * @version 0.1, 06/18/2020 + */ +public class SampleIdpExternalScriptService extends ExternalScriptService { + + private static final long serialVersionUID = -1316361273036208685L; + + public SampleIdpExternalScriptService() { + super(CustomScriptType.IDP); + } + + // boolean translateAttributes(Object context, Map configurationAttributes); + + public boolean executeExternalTranslateAttributesMethod(Object context, CustomScriptConfiguration customScriptConfiguration) { + try { + log.debug("Executing python 'translateAttributes' method"); + IdpType idpType = (IdpType) customScriptConfiguration.getExternalType(); + Map configurationAttributes = customScriptConfiguration.getConfigurationAttributes(); + return idpType.translateAttributes(context, configurationAttributes); + } catch (Exception ex) { + log.error(ex.getMessage(), ex); + saveScriptError(customScriptConfiguration.getCustomScript(), ex); + } + + return false; + } + + public boolean executeExternalTranslateAttributesMethod(Object context) { + boolean result = true; + for (CustomScriptConfiguration customScriptConfiguration : this.customScriptConfigurations) { + if (customScriptConfiguration.getExternalType().getApiVersion() > 1) { + result &= executeExternalTranslateAttributesMethod(context, customScriptConfiguration); + if (!result) { + return result; + } + } + } + + return result; + } + + // boolean updateAttributes(Object context, Map configurationAttributes); + + public boolean executeExternalUpdateAttributesMethod(Object context, CustomScriptConfiguration customScriptConfiguration) { + try { + log.debug("Executing python 'updateAttributes' method"); + IdpType idpType = (IdpType) customScriptConfiguration.getExternalType(); + Map configurationAttributes = customScriptConfiguration.getConfigurationAttributes(); + return idpType.updateAttributes(context, configurationAttributes); + } catch (Exception ex) { + log.error(ex.getMessage(), ex); + saveScriptError(customScriptConfiguration.getCustomScript(), ex); + } + + return false; + } + + public boolean executeExternalUpdateAttributesMethods(Object context) { + boolean result = true; + for (CustomScriptConfiguration customScriptConfiguration : this.customScriptConfigurations) { + if (customScriptConfiguration.getExternalType().getApiVersion() > 1) { + result &= executeExternalUpdateAttributesMethod(context, customScriptConfiguration); + if (!result) { + return result; + } + } + } + + return result; + } + +} diff --git a/core-script/src/test/java/org/gluu/service/custom/script/test/StandaloneCustomScriptManagerTest.java b/core-script/src/test/java/org/gluu/service/custom/script/test/StandaloneCustomScriptManagerTest.java new file mode 100644 index 000000000..2a4b54a57 --- /dev/null +++ b/core-script/src/test/java/org/gluu/service/custom/script/test/StandaloneCustomScriptManagerTest.java @@ -0,0 +1,87 @@ +package org.gluu.service.custom.script.test; + +import java.util.Properties; + +import org.apache.log4j.Logger; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.status.StatusLogger; +import org.gluu.log.LoggingHelper; +import org.gluu.persist.PersistenceEntryManager; +import org.gluu.persist.ldap.impl.LdapEntryManager; +import org.gluu.persist.ldap.impl.LdapEntryManagerFactory; +import org.gluu.service.custom.script.StandaloneCustomScriptManager; + +public class StandaloneCustomScriptManagerTest { + + private static final Logger LOG = Logger.getLogger(StandaloneCustomScriptManagerTest.class); + + static { + StatusLogger.getLogger().setLevel(Level.OFF); + LoggingHelper.configureConsoleAppender(); + } + + private static Properties getSampleConnectionProperties() { + Properties connectionProperties = new Properties(); + + connectionProperties.put("ldap.bindDN", "cn=Directory Manager"); + connectionProperties.put("ldap.bindPassword", "secret"); +// connectionProperties.put("ldap.bindPassword", "test"); + connectionProperties.put("ldap.servers", "localhost:1636"); + connectionProperties.put("ldap.useSSL", "true"); + connectionProperties.put("ldap.maxconnections", "3"); + + return connectionProperties; + } + + public static LdapEntryManager createLdapEntryManager() { + LdapEntryManagerFactory ldapEntryManagerFactory = new LdapEntryManagerFactory(); + Properties connectionProperties = getSampleConnectionProperties(); + + LdapEntryManager ldapEntryManager = ldapEntryManagerFactory.createEntryManager(connectionProperties); + LOG.debug("Created LdapEntryManager: " + ldapEntryManager); + + return ldapEntryManager; + } + + public static void main(String[] args) { + if (System.getenv("PYTHON_HOME") == null) { + System.err.println("PYTHON_HOME environment variable is not defined"); + System.exit(-1); + } + + PersistenceEntryManager persistenceEntryManager = createLdapEntryManager(); + StandaloneCustomScriptManager customScriptManager = new StandaloneCustomScriptManager(persistenceEntryManager, "ou=scripts,o=gluu", "/opt/gluu/python/libs"); + + // Register required external scripts + SampleIdpExternalScriptService sampleIdpExternalScriptService = new SampleIdpExternalScriptService(); + customScriptManager.registerExternalScriptService(sampleIdpExternalScriptService); + + // Init script manager and load scripts + customScriptManager.init(); + + // Call script + Object context = new SampleContext(System.currentTimeMillis()); + sampleIdpExternalScriptService.executeExternalUpdateAttributesMethods(context); + + // Reload script if needed + customScriptManager.reload(); + + // Call script + Object context2 = new SampleContext(System.currentTimeMillis()); + sampleIdpExternalScriptService.executeExternalUpdateAttributesMethods(context2); + + // Destroy custom script manager and scripts + customScriptManager.destory(); + } + + private static class SampleContext { + + long time; + + public SampleContext(long time) { + super(); + this.time = time; + } + } + +} diff --git a/core-standalone/pom.xml b/core-standalone/pom.xml new file mode 100644 index 000000000..c9b0a9a15 --- /dev/null +++ b/core-standalone/pom.xml @@ -0,0 +1,65 @@ + + + 4.0.0 + org.gluu + oxcore-standalone + Configuration factories for standalone applications + + + org.gluu + oxcore + 4.5.6-SNAPSHOT + + + + ${maven.min-version} + + + + + + src/main/resources + true + + **/*.xml + **/services/* + **/*.properties + + + + + + src/test/resources + true + + **/*.xml + **/services/* + **/*.properties + + + + + + + + org.gluu + gluu-orm-cdi + + + org.gluu + oxcore-cache + + + org.gluu + gluu-orm-standalone + + + + + org.testng + testng + + + + \ No newline at end of file diff --git a/core-standalone/src/main/java/org/gluu/conf/model/AppConfiguration.java b/core-standalone/src/main/java/org/gluu/conf/model/AppConfiguration.java new file mode 100644 index 000000000..c6f8cf764 --- /dev/null +++ b/core-standalone/src/main/java/org/gluu/conf/model/AppConfiguration.java @@ -0,0 +1,101 @@ +/* + * oxTrust is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2014, Gluu + */ + +package org.gluu.conf.model; + +import java.io.Serializable; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + + +/** + * Base application configuration + * + * @author Yuriy Movchan + * @version 0.1, 11/02/2015 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class AppConfiguration implements Serializable { + + private static final long serialVersionUID = -587414854758989561L; + + private String applicationName; + private String openIdProviderUrl; + private String openIdClientId; + private String openIdClientPassword; + private List openIdScopes; + private String openIdRedirectUrl; + + private String openIdPostLogoutRedirectUri; + + private List openIdClaimMapping; + + public String getApplicationName() { + return applicationName; + } + + public void setApplicationName(String applicationName) { + this.applicationName = applicationName; + } + + public String getOpenIdProviderUrl() { + return openIdProviderUrl; + } + + public void setOpenIdProviderUrl(String openIdProviderUrl) { + this.openIdProviderUrl = openIdProviderUrl; + } + + public String getOpenIdClientId() { + return openIdClientId; + } + + public void setOpenIdClientId(String openIdClientId) { + this.openIdClientId = openIdClientId; + } + + public String getOpenIdClientPassword() { + return openIdClientPassword; + } + + public void setOpenIdClientPassword(String openIdClientPassword) { + this.openIdClientPassword = openIdClientPassword; + } + + public List getOpenIdScopes() { + return openIdScopes; + } + + public void setOpenIdScopes(List openIdScopes) { + this.openIdScopes = openIdScopes; + } + + public String getOpenIdRedirectUrl() { + return openIdRedirectUrl; + } + + public void setOpenIdRedirectUrl(String openIdRedirectUrl) { + this.openIdRedirectUrl = openIdRedirectUrl; + } + + public List getOpenIdClaimMapping() { + return openIdClaimMapping; + } + + public void setOpenIdClaimMapping(List openIdClaimMapping) { + this.openIdClaimMapping = openIdClaimMapping; + } + + public String getOpenIdPostLogoutRedirectUri() { + return openIdPostLogoutRedirectUri; + } + + public void setOpenIdPostLogoutRedirectUri(String openIdPostLogoutRedirectUri) { + this.openIdPostLogoutRedirectUri = openIdPostLogoutRedirectUri; + } + +} diff --git a/core-standalone/src/main/java/org/gluu/conf/model/AppConfigurationEntry.java b/core-standalone/src/main/java/org/gluu/conf/model/AppConfigurationEntry.java new file mode 100644 index 000000000..b183d3e1f --- /dev/null +++ b/core-standalone/src/main/java/org/gluu/conf/model/AppConfigurationEntry.java @@ -0,0 +1,63 @@ +/* + * oxTrust is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2014, Gluu + */ + +package org.gluu.conf.model; + +import java.io.Serializable; + +import org.gluu.persist.annotation.AttributeName; +import org.gluu.persist.annotation.DN; +import org.gluu.persist.annotation.DataEntry; +import org.gluu.persist.annotation.JsonObject; +import org.gluu.persist.annotation.ObjectClass; + +/** + * @author Yuriy Movchan + * @version 0.1, 03/25/2016 + */ +@DataEntry +@ObjectClass(value = "oxApplicationConfiguration") +public class AppConfigurationEntry implements Serializable { + + private static final long serialVersionUID = 1847361642302974184L; + + @DN + private String dn; + + @AttributeName(name = "oxRevision") + private long revision; + + @JsonObject + @AttributeName(name = "oxConfApplication") + private AppConfiguration application; + + public AppConfigurationEntry() {} + + public String getDn() { + return dn; + } + + public void setDn(String dn) { + this.dn = dn; + } + + public long getRevision() { + return revision; + } + + public void setRevision(long revision) { + this.revision = revision; + } + + public AppConfiguration getApplication() { + return application; + } + + public void setApplication(AppConfiguration application) { + this.application = application; + } + +} diff --git a/core-standalone/src/main/java/org/gluu/conf/model/ClaimToAttributeMapping.java b/core-standalone/src/main/java/org/gluu/conf/model/ClaimToAttributeMapping.java new file mode 100644 index 000000000..b9f0512d6 --- /dev/null +++ b/core-standalone/src/main/java/org/gluu/conf/model/ClaimToAttributeMapping.java @@ -0,0 +1,53 @@ +/* + * oxTrust is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2014, Gluu + */ + +/** + * CAS oxAuth application configuration + * + * @author Yuriy Movchan + * @version 0.1, 03/25/2016 + */ +package org.gluu.conf.model; + +import java.io.Serializable; + +/** + * Claim to attribute mapping + * + * @author Yuriy Movchan + * @version 0.1, 03/25/2016 + */ +public class ClaimToAttributeMapping implements Serializable { + + private static final long serialVersionUID = 3450326508968717097L; + + private String claim; + private String attribute; + + public String getClaim() { + return claim; + } + + public void setClaim(String claim) { + this.claim = claim; + } + + public String getAttribute() { + return attribute; + } + + public void setAttribute(String attribute) { + this.attribute = attribute; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("ClaimToAttributeMapping [claim=").append(claim).append(", attribute=").append(attribute).append("]"); + return builder.toString(); + } + +} diff --git a/core-standalone/src/main/java/org/gluu/conf/model/SharedConfigurationEntry.java b/core-standalone/src/main/java/org/gluu/conf/model/SharedConfigurationEntry.java new file mode 100644 index 000000000..77956a2b5 --- /dev/null +++ b/core-standalone/src/main/java/org/gluu/conf/model/SharedConfigurationEntry.java @@ -0,0 +1,125 @@ +/* + * oxTrust is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2014, Gluu + */ + +package org.gluu.conf.model; + +import java.io.Serializable; +import java.util.Date; + +import org.gluu.model.SmtpConfiguration; +import org.gluu.persist.annotation.AttributeName; +import org.gluu.persist.annotation.CustomObjectClass; +import org.gluu.persist.annotation.DataEntry; +import org.gluu.persist.annotation.JsonObject; +import org.gluu.persist.annotation.ObjectClass; +import org.gluu.persist.model.base.InumEntry; +import org.gluu.service.cache.CacheConfiguration; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +/** + * GluuConfiguration + * + * @author Yuriy Movchan Date: 01/21/2020 + */ +@DataEntry +@ObjectClass(value = "gluuConfiguration") +@JsonIgnoreProperties(ignoreUnknown = true) +public class SharedConfigurationEntry extends InumEntry implements Serializable { + + private static final long serialVersionUID = -1817003894646725601L; + + @AttributeName + private String description; + + @AttributeName + private String displayName; + + @AttributeName(name = "gluuLastUpdate", updateOnly = true) + private Date lastUpdate; + + @AttributeName(name = "gluuConfigurationPollingInterval") + private String pollingInterval; + + @AttributeName(name = "oxTrustEmail") + private String contactEmail; + + @AttributeName(name = "oxSmtpConfiguration") + @JsonObject + private SmtpConfiguration smtpConfiguration; + + @AttributeName(name = "oxCacheConfiguration") + @JsonObject + private CacheConfiguration cacheConfiguration; + + @CustomObjectClass + private String[] customObjectClasses; + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + public Date getLastUpdate() { + return lastUpdate; + } + + public void setLastUpdate(Date lastUpdate) { + this.lastUpdate = lastUpdate; + } + + public String getPollingInterval() { + return pollingInterval; + } + + public void setPollingInterval(String pollingInterval) { + this.pollingInterval = pollingInterval; + } + + public String getContactEmail() { + return contactEmail; + } + + public void setContactEmail(String contactEmail) { + this.contactEmail = contactEmail; + } + + public SmtpConfiguration getSmtpConfiguration() { + return smtpConfiguration; + } + + public void setSmtpConfiguration(SmtpConfiguration smtpConfiguration) { + this.smtpConfiguration = smtpConfiguration; + } + + public CacheConfiguration getCacheConfiguration() { + return cacheConfiguration; + } + + public void setCacheConfiguration(CacheConfiguration cacheConfiguration) { + this.cacheConfiguration = cacheConfiguration; + } + + public String[] getCustomObjectClasses() { + return customObjectClasses; + } + + public void setCustomObjectClasses(String[] customObjectClasses) { + this.customObjectClasses = customObjectClasses; + } + +} \ No newline at end of file diff --git a/core-standalone/src/main/java/org/gluu/conf/service/ConfigurationFactory.java b/core-standalone/src/main/java/org/gluu/conf/service/ConfigurationFactory.java new file mode 100644 index 000000000..f1e75507c --- /dev/null +++ b/core-standalone/src/main/java/org/gluu/conf/service/ConfigurationFactory.java @@ -0,0 +1,322 @@ +/* + * oxTrust is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2014, Gluu + */ + +package org.gluu.conf.service; + +import java.io.File; +import java.util.Properties; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.commons.lang.StringUtils; +import org.gluu.conf.model.AppConfiguration; +import org.gluu.conf.model.AppConfigurationEntry; +import org.gluu.conf.model.SharedConfigurationEntry; +import org.gluu.persist.PersistenceEntryManager; +import org.gluu.persist.PersistenceEntryManagerFactory; +import org.gluu.persist.exception.BasePersistenceException; +import org.gluu.persist.model.PersistenceConfiguration; +import org.gluu.persist.service.PersistanceFactoryService; +import org.gluu.persist.service.StandalonePersistanceFactoryService; +import org.gluu.service.cache.CacheConfiguration; +import org.gluu.service.cache.InMemoryConfiguration; +import org.gluu.util.StringHelper; +import org.gluu.util.exception.ConfigurationException; +import org.gluu.orm.util.properties.FileConfiguration; +import org.gluu.util.security.PropertiesDecrypter; +import org.gluu.util.security.StringEncrypter; +import org.gluu.util.security.StringEncrypter.EncryptionException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Base OpenId configuration + * + * @author Yuriy Movchan + * @version 0.1, 11/02/2015 + */ +public abstract class ConfigurationFactory { + + private final Logger LOG = LoggerFactory.getLogger(ConfigurationFactory.class); + + static { + if (System.getProperty("gluu.base") != null) { + BASE_DIR = System.getProperty("gluu.base"); + } else if ((System.getProperty("catalina.base") != null) && (System.getProperty("catalina.base.ignore") == null)) { + BASE_DIR = System.getProperty("catalina.base"); + } else if (System.getProperty("catalina.home") != null) { + BASE_DIR = System.getProperty("catalina.home"); + } else if (System.getProperty("jboss.home.dir") != null) { + BASE_DIR = System.getProperty("jboss.home.dir"); + } else { + BASE_DIR = null; + } + } + + public static final String BASE_DIR; + public static final String DIR = BASE_DIR + File.separator + "conf" + File.separator; + + private static final String BASE_PROPERTIES_FILE = DIR + "gluu.properties"; + public static final String DEFAULT_PROPERTIES_FILE = DIR + "openid.properties"; + + private static final String SALT_FILE_NAME = "salt"; + + private static final String SHARED_CONFIGURATION_DN = "ou=configuration,o=gluu"; + + private String confDir, saltFilePath; + + private FileConfiguration baseConfiguration; + + private C appConfiguration; + + private PersistanceFactoryService persistanceFactoryService; + private PersistenceConfiguration persistenceConfiguration; + + private String cryptoConfigurationSalt; + private StringEncrypter stringEncrypter; + + private PersistenceEntryManager persistenceEntryManager; + + private CacheConfiguration cacheConfiguration; + + @SuppressWarnings("unused") + private long baseConfigurationFileLastModifiedTime; + + private boolean loaded = false; + private long loadedRevision = -1; + + private AtomicBoolean isActive; + + protected ConfigurationFactory() { + this.isActive = new AtomicBoolean(true); + try { + create(); + } finally { + this.isActive.set(false); + } + } + + private void create() { + this.persistanceFactoryService = new StandalonePersistanceFactoryService(); + + this.persistenceConfiguration = persistanceFactoryService.loadPersistenceConfiguration(getDefaultConfigurationFileName()); + this.baseConfiguration = loadBaseConfiguration(); + + this.confDir = confDir(); + this.saltFilePath = confDir + SALT_FILE_NAME; + + this.cryptoConfigurationSalt = loadCryptoConfigurationSalt(); + this.stringEncrypter = createStringEncrypter(); + + this.persistenceEntryManager = createPersistenceEntryManager(); + + if (!createFromDb()) { + LOG.error("Failed to load configuration from DB. Please fix it!!!."); + throw new ConfigurationException("Failed to load configuration from DB."); + } else { + this.loaded = true; + LOG.info("Configuration loaded successfully."); + } + + this.cacheConfiguration = loadCacheConfiguration(); + } + + public void destroy() { + if (this.persistenceEntryManager != null) { + destroyPersistenceEntryManager(this.persistenceEntryManager); + } + } + + private FileConfiguration createFileConfiguration(String fileName, boolean isMandatory) { + try { + FileConfiguration fileConfiguration = new FileConfiguration(fileName); + + return fileConfiguration; + } catch (Exception ex) { + if (isMandatory) { + LOG.error("Failed to load configuration from {}", fileName, ex); + throw new ConfigurationException("Failed to load configuration from " + fileName, ex); + } + } + + return null; + } + + private FileConfiguration loadBaseConfiguration() { + FileConfiguration fileConfiguration = createFileConfiguration(BASE_PROPERTIES_FILE, true); + + return fileConfiguration; + } + + private String loadCryptoConfigurationSalt() { + try { + FileConfiguration cryptoConfiguration = new FileConfiguration(this.saltFilePath); + + return cryptoConfiguration.getString("encodeSalt"); + } catch (Exception ex) { + LOG.error("Failed to load configuration from {}", saltFilePath, ex); + throw new ConfigurationException("Failed to load configuration from " + saltFilePath, ex); + } + } + + private CacheConfiguration loadCacheConfiguration() { + SharedConfigurationEntry sharedConfigurationEntry = persistenceEntryManager.find(SharedConfigurationEntry.class, SHARED_CONFIGURATION_DN); + if (sharedConfigurationEntry == null) { + LOG.error("Failed to load share configuration from DB. Please fix it!!!."); + throw new ConfigurationException("Failed to load shared configuration from DB."); + } + + CacheConfiguration cacheConfiguration = sharedConfigurationEntry.getCacheConfiguration(); + if (cacheConfiguration == null || cacheConfiguration.getCacheProviderType() == null) { + LOG.error("Failed to read cache configuration from DB. Please check configuration oxCacheConfiguration attribute " + + "that must contain cache configuration JSON represented by CacheConfiguration.class. Shared configuration DN: " + SHARED_CONFIGURATION_DN); + LOG.info("Creating fallback IN-MEMORY cache configuration ... "); + + cacheConfiguration = new CacheConfiguration(); + cacheConfiguration.setInMemoryConfiguration(new InMemoryConfiguration()); + + LOG.info("IN-MEMORY cache configuration is created."); + } + LOG.info("Cache configuration: " + cacheConfiguration); + + return cacheConfiguration; + } + + private String confDir() { + final String confDir = getPersistenceConfiguration().getString("confDir"); + if (StringUtils.isNotBlank(confDir)) { + return confDir; + } + + return DIR; + } + + private boolean createFromDb() { + LOG.info("Loading configuration from '{}' DB...", baseConfiguration.getString("persistence.type")); + try { + final L persistenceConf = loadConfigurationFromDb(); + this.loadedRevision = persistenceConf.getRevision(); + if (persistenceConf != null) { + this.appConfiguration = (C) persistenceConf.getApplication(); + return true; + } + } catch (Exception ex) { + LOG.error(ex.getMessage(), ex); + } + + return false; + } + + private L loadConfigurationFromDb(String... returnAttributes) { + try { + final String dn = baseConfiguration.getString(getApplicationConfigurationPropertyName()); + + final L persistanceConf = this.persistenceEntryManager.find(dn, getAppConfigurationType(), returnAttributes); + return persistanceConf; + } catch (BasePersistenceException ex) { + LOG.error(ex.getMessage()); + } + + return null; + } + + protected Properties preparePersistanceProperties() { + FileConfiguration persistenceConfig = persistenceConfiguration.getConfiguration(); + Properties connectionProperties = (Properties) persistenceConfig.getProperties(); + + Properties decryptedConnectionProperties; + try { + decryptedConnectionProperties = PropertiesDecrypter.decryptAllProperties(StringEncrypter.defaultInstance(), connectionProperties, this.cryptoConfigurationSalt); + } catch (EncryptionException ex) { + throw new ConfigurationException("Failed to decript configuration properties", ex); + } + + return decryptedConnectionProperties; + } + + private PersistenceEntryManager createPersistenceEntryManager() { + Properties connectionProperties = preparePersistanceProperties(); + + PersistenceEntryManagerFactory persistenceEntryManagerFactory = persistanceFactoryService.getPersistenceEntryManagerFactory(persistenceConfiguration); + PersistenceEntryManager persistenceEntryManager = persistenceEntryManagerFactory.createEntryManager(connectionProperties); + LOG.info("Created PersistenceEntryManager: {} with operation service: {}", + new Object[] {persistenceEntryManager, + persistenceEntryManager.getOperationService() }); + + return persistenceEntryManager; + } + + private void destroyPersistenceEntryManager(final PersistenceEntryManager persistenceEntryManager) { + boolean result = persistenceEntryManager.destroy(); + if (result) { + LOG.debug("Destoyed PersistenceEntryManager: {}", persistenceEntryManager); + } else { + LOG.error("Failed to destoy PersistenceEntryManager: {}", persistenceEntryManager); + } + } + + private StringEncrypter createStringEncrypter() { + String encodeSalt = this.cryptoConfigurationSalt; + + if (StringHelper.isEmpty(encodeSalt)) { + throw new ConfigurationException("Encode salt isn't defined"); + } + + try { + StringEncrypter stringEncrypter = StringEncrypter.instance(encodeSalt); + + return stringEncrypter; + } catch (EncryptionException ex) { + throw new ConfigurationException("Failed to create StringEncrypter instance"); + } + } + + public StringEncrypter getStringEncrypter() { + return stringEncrypter; + } + + public FileConfiguration getPersistenceConfiguration() { + return this.persistenceConfiguration.getConfiguration(); + } + + public FileConfiguration getBaseConfiguration() { + return baseConfiguration; + } + + public String getCryptoConfigurationSalt() { + return cryptoConfigurationSalt; + } + + public PersistenceEntryManager getPersistenceEntryManager() { + return persistenceEntryManager; + } + + protected String getDefaultPersistanceConfigurationFileName() { + return "gluu-ldap.properties"; + } + + public C getAppConfiguration() { + return appConfiguration; + } + + public CacheConfiguration getCacheConfiguration() { + return cacheConfiguration; + } + + public boolean isLoaded() { + return loaded; + } + + public long getLoadedRevision() { + return loadedRevision; + } + + protected abstract String getDefaultConfigurationFileName(); + + protected abstract Class getAppConfigurationType(); + + protected abstract String getApplicationConfigurationPropertyName(); + +} diff --git a/core-standalone/src/test/java/org/gluu/conf/service/DummyConfigurationFactory.java b/core-standalone/src/test/java/org/gluu/conf/service/DummyConfigurationFactory.java new file mode 100644 index 000000000..2c981e073 --- /dev/null +++ b/core-standalone/src/test/java/org/gluu/conf/service/DummyConfigurationFactory.java @@ -0,0 +1,27 @@ +package org.gluu.conf.service; + +import org.gluu.conf.model.AppConfiguration; +import org.gluu.conf.model.AppConfigurationEntry; + +/** + * @author Yuriy Movchan + * @version 0.1, 01/02/2020 + */ +public class DummyConfigurationFactory extends ConfigurationFactory { + + @Override + protected String getDefaultConfigurationFileName() { + return "gluu-dummy.properties"; + } + + @Override + protected Class getAppConfigurationType() { + return AppConfigurationEntry.class; + } + + @Override + protected String getApplicationConfigurationPropertyName() { + return "oxdummyConfigurationEntryDN"; + } + +} diff --git a/core-standalone/src/test/java/org/gluu/conf/service/DummyConfigurationFactoryTest.java b/core-standalone/src/test/java/org/gluu/conf/service/DummyConfigurationFactoryTest.java new file mode 100644 index 000000000..7e0cbc363 --- /dev/null +++ b/core-standalone/src/test/java/org/gluu/conf/service/DummyConfigurationFactoryTest.java @@ -0,0 +1,34 @@ +package org.gluu.conf.service; + +import static org.testng.Assert.assertNotNull; + +import org.gluu.service.cache.CacheConfiguration; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** + * @author Yuriy Movchan + * @version 0.1, 01/02/2020 + */ +public class DummyConfigurationFactoryTest { + + private DummyConfigurationFactory dummyConfigurationFactory; + + @BeforeClass + public void beforeClass() { + this.dummyConfigurationFactory = new DummyConfigurationFactory(); + } + + @Test(enabled = false) + public void checkAppConfigurationLoad() { + assertNotNull(dummyConfigurationFactory.getAppConfiguration()); + } + + @Test(enabled = false) + public void checkCacheConfiguration() { + CacheConfiguration cacheConfiguration = dummyConfigurationFactory.getCacheConfiguration(); + assertNotNull(cacheConfiguration); + assertNotNull(cacheConfiguration.getCacheProviderType()); + } + +} diff --git a/core-timer-weld/pom.xml b/core-timer-weld/pom.xml new file mode 100644 index 000000000..e5ab68787 --- /dev/null +++ b/core-timer-weld/pom.xml @@ -0,0 +1,76 @@ + + + 4.0.0 + oxcore-timer-weld + Weld CDI timer implementation + + + org.gluu + oxcore + 4.5.6-SNAPSHOT + + + + ${maven.min-version} + + + + + + src/main/resources + true + + **/*.xml + **/services/* + **/*.properties + + + + + + + + + ${project.groupId} + oxcore-cdi + + + ${project.groupId} + oxcore-util + + + + + org.slf4j + slf4j-api + provided + + + + + javax.enterprise + cdi-api + provided + + + org.jboss.spec.javax.annotation + jboss-annotations-api_1.2_spec + provided + + + + + org.jboss.weld + weld-core-impl + provided + + + + + org.quartz-scheduler + quartz + + + + \ No newline at end of file diff --git a/oxService/src/main/java/org/gluu/service/timer/JobExecutionDelegate.java b/core-timer-weld/src/main/java/org/gluu/service/timer/JobExecutionDelegate.java similarity index 100% rename from oxService/src/main/java/org/gluu/service/timer/JobExecutionDelegate.java rename to core-timer-weld/src/main/java/org/gluu/service/timer/JobExecutionDelegate.java diff --git a/oxService/src/main/java/org/gluu/service/timer/JobExecutionFactory.java b/core-timer-weld/src/main/java/org/gluu/service/timer/JobExecutionFactory.java similarity index 100% rename from oxService/src/main/java/org/gluu/service/timer/JobExecutionFactory.java rename to core-timer-weld/src/main/java/org/gluu/service/timer/JobExecutionFactory.java diff --git a/oxService/src/main/java/org/gluu/service/timer/QuartzSchedulerManager.java b/core-timer-weld/src/main/java/org/gluu/service/timer/QuartzSchedulerManager.java similarity index 100% rename from oxService/src/main/java/org/gluu/service/timer/QuartzSchedulerManager.java rename to core-timer-weld/src/main/java/org/gluu/service/timer/QuartzSchedulerManager.java diff --git a/oxService/src/main/java/org/gluu/service/timer/RequestJobListener.java b/core-timer-weld/src/main/java/org/gluu/service/timer/RequestJobListener.java similarity index 100% rename from oxService/src/main/java/org/gluu/service/timer/RequestJobListener.java rename to core-timer-weld/src/main/java/org/gluu/service/timer/RequestJobListener.java diff --git a/oxService/src/main/java/org/gluu/service/timer/TimerJob.java b/core-timer-weld/src/main/java/org/gluu/service/timer/TimerJob.java similarity index 95% rename from oxService/src/main/java/org/gluu/service/timer/TimerJob.java rename to core-timer-weld/src/main/java/org/gluu/service/timer/TimerJob.java index db7ba9ee2..2f6b84642 100644 --- a/oxService/src/main/java/org/gluu/service/timer/TimerJob.java +++ b/core-timer-weld/src/main/java/org/gluu/service/timer/TimerJob.java @@ -32,10 +32,8 @@ public void execute(JobExecutionContext context) throws JobExecutionException { if (timerEvent == null) { return; } - - log.debug("Fire timer event [{}] with qualifiers {} from instance {}", timerEvent.getTargetEvent().getClass().getName(), + log.trace("Fire timer event [{}] with qualifiers {} from instance {}", timerEvent.getTargetEvent().getClass().getName(), timerEvent.getQualifiers(), System.identityHashCode(this)); - beanManager.fireEvent(timerEvent.getTargetEvent(), timerEvent.getQualifiers()); } catch (Exception ex) { throw new JobExecutionException(ex); diff --git a/core-timer-weld/src/main/resources/META-INF/beans.xml b/core-timer-weld/src/main/resources/META-INF/beans.xml new file mode 100644 index 000000000..2f4f7e279 --- /dev/null +++ b/core-timer-weld/src/main/resources/META-INF/beans.xml @@ -0,0 +1,7 @@ + + + diff --git a/demo-cdi/pom.xml b/demo-cdi/pom.xml index fcd65af09..d868e7667 100644 --- a/demo-cdi/pom.xml +++ b/demo-cdi/pom.xml @@ -2,14 +2,13 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.gluu oxcore-demo-cdi Demo CDI services org.gluu oxcore - 4.0.0-SNAPSHOT + 4.5.6-SNAPSHOT @@ -45,11 +44,10 @@ provided - + org.jboss.resteasy - resteasy-jaxrs - provided + resteasy-cdi diff --git a/doc/pom.xml b/doc/pom.xml new file mode 100644 index 000000000..c88fa3e99 --- /dev/null +++ b/doc/pom.xml @@ -0,0 +1,15 @@ + + + org.gluu + oxcore + 4.5.6-SNAPSHOT + + + 4.0.0 + gluu-doc + jar + gluu-doc + + + diff --git a/doc/src/main/java/org/gluu/doc/annotation/DocFeatureFlag.java b/doc/src/main/java/org/gluu/doc/annotation/DocFeatureFlag.java new file mode 100644 index 000000000..613fde79f --- /dev/null +++ b/doc/src/main/java/org/gluu/doc/annotation/DocFeatureFlag.java @@ -0,0 +1,16 @@ +package org.gluu.doc.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.SOURCE) +public @interface DocFeatureFlag { + String description(); + + boolean isRequired() default false; + + String defaultValue(); +} diff --git a/doc/src/main/java/org/gluu/doc/annotation/DocFeatureFlagProcessor.java b/doc/src/main/java/org/gluu/doc/annotation/DocFeatureFlagProcessor.java new file mode 100644 index 000000000..f9c401965 --- /dev/null +++ b/doc/src/main/java/org/gluu/doc/annotation/DocFeatureFlagProcessor.java @@ -0,0 +1,112 @@ +package org.gluu.doc.annotation; + +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.annotation.processing.SupportedOptions; +import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; +import javax.tools.Diagnostic; +import javax.tools.FileObject; +import javax.tools.StandardLocation; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +@SupportedAnnotationTypes("org.gluu.doc.annotation.DocFeatureFlag") +@SupportedOptions({"module"}) +public class DocFeatureFlagProcessor extends AbstractProcessor { + + String moduleName; + @Override + public boolean process(Set annotations, RoundEnvironment env) { + + moduleName = processingEnv.getOptions().get("module"); + + for (TypeElement annotation : annotations) { + Set annotatedElements = env.getElementsAnnotatedWith(annotation); + + // sort alphabetically + List sortedElements = annotatedElements.stream() + .sorted((prop1, prop2)->prop1.getSimpleName().toString().toLowerCase().compareTo(prop2.getSimpleName().toString().toLowerCase())) + .collect(Collectors.toList()); + + StringBuilder docContents = new StringBuilder(); + StringBuilder tableContents = new StringBuilder(); + StringBuilder detailsContent = new StringBuilder(); + + // prepare document header + prepareDocTagsAndTableHeader(docContents, tableContents); + + // for each feature flag add a row in table and add content for the details section + for (Element element : sortedElements) + { + DocFeatureFlag elementAnnotation = element.getAnnotation(DocFeatureFlag.class); + addToTable(tableContents, element, elementAnnotation); + addToDetails(detailsContent, element, elementAnnotation); + } + tableContents.append("\n\n"); + createAndWriteDoc(docContents.append((tableContents.append(detailsContent.toString())))); + + } + return false; + } + + private void prepareDocTagsAndTableHeader(StringBuilder docContents, StringBuilder tableContents) { + // add tags + docContents.append("---\n") + .append("tags:\n") + .append("- administration\n") + .append("- reference\n") + .append("- json\n") + .append("- feature-flags\n") + .append("---\n") + .append("\n") + .append("# "+moduleName+" Feature Flags") // add doc header + .append("\n") + .append("\n"); + + tableContents.append("| Feature Flag Name ") // prepare table header + .append("| Description ") + .append("| | ") + .append("\n") + .append("|-----|-----|-----|") + .append("\n"); + } + + private void createAndWriteDoc(StringBuilder docContent) { + + FileObject docFile = null; + try{ + docFile = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", moduleName.toLowerCase().replaceAll("\\s", "")+"-feature-flags.md"); + } + catch (IOException ioe){ + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, this.getClass().getName()+": Error occurred while creating annotation documentation file"); + } + if(docFile!=null){ + try(PrintWriter docWriter = new PrintWriter(docFile.openWriter());) { + docWriter.write(docContent.toString()); + docWriter.flush(); + } catch (IOException e) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, this.getClass().getName()+": Error occurred while writing annotation documentation file"); + } + } + } + + private static void addToDetails(StringBuilder propDetails, Element jansElement, DocFeatureFlag featureFlagAnnotation) { + propDetails.append("### "+ jansElement.getSimpleName()+"\n\n"); + propDetails.append("- Description: "+ featureFlagAnnotation.description()+"\n\n"); + propDetails.append("- Required: "+ (featureFlagAnnotation.isRequired()?"Yes":"No")+"\n\n"); + propDetails.append("- Default value: "+ featureFlagAnnotation.defaultValue()+"\n\n"); + propDetails.append("\n"); + } + + private static void addToTable(StringBuilder propTable, Element jansElement, DocFeatureFlag featureFlagAnnotation) { + propTable.append("| "+ jansElement.getSimpleName()+" "); + propTable.append("| "+ featureFlagAnnotation.description()+" "); + propTable.append("| [Details](#"+jansElement.getSimpleName().toString().toLowerCase()+") |"); + propTable.append("\n"); + } +} diff --git a/doc/src/main/java/org/gluu/doc/annotation/DocProperty.java b/doc/src/main/java/org/gluu/doc/annotation/DocProperty.java new file mode 100644 index 000000000..e2126c860 --- /dev/null +++ b/doc/src/main/java/org/gluu/doc/annotation/DocProperty.java @@ -0,0 +1,16 @@ +package org.gluu.doc.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.SOURCE) +public @interface DocProperty { + String description() default "None"; + + boolean isRequired() default false; + + String defaultValue() default "None"; +} diff --git a/doc/src/main/java/org/gluu/doc/annotation/DocPropertyProcessor.java b/doc/src/main/java/org/gluu/doc/annotation/DocPropertyProcessor.java new file mode 100644 index 000000000..614703b22 --- /dev/null +++ b/doc/src/main/java/org/gluu/doc/annotation/DocPropertyProcessor.java @@ -0,0 +1,120 @@ +package org.gluu.doc.annotation; + +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.annotation.processing.SupportedOptions; +import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; +import javax.tools.Diagnostic; +import javax.tools.FileObject; +import javax.tools.StandardLocation; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +@SupportedAnnotationTypes("org.gluu.doc.annotation.DocProperty") +@SupportedOptions({"module"}) +public class DocPropertyProcessor extends AbstractProcessor { + + String moduleName; + + // This method would be called once per class containing annotated elements + @Override + public boolean process(Set annotations, RoundEnvironment env) { + + moduleName = processingEnv.getOptions().get("module"); + + // Loop iterates once per supported annotation type by this processor + for (TypeElement annotation : annotations) { + + // Get all the elements that are annotated by a particular annotation located across classes in this module + Set annotatedProperties = env.getElementsAnnotatedWith(annotation); + + // sort alphabetically + List sortedProperties = annotatedProperties.stream() + .sorted((prop1, prop2)->prop1.getSimpleName().toString().toLowerCase().compareTo(prop2.getSimpleName().toString().toLowerCase())) + .collect(Collectors.toList()); + + StringBuilder docContents = new StringBuilder(); + StringBuilder tableContents = new StringBuilder(); + StringBuilder detailsContent = new StringBuilder(); + + // prepare document header + prepareDocTagsAndTableHeader(docContents, tableContents); + + // for each property add a row in table and add content for the details section + for (Element jansProperty : sortedProperties) + { + DocProperty propertyAnnotation = jansProperty.getAnnotation(DocProperty.class); + addToTable(tableContents, jansProperty, propertyAnnotation); + addToDetails(detailsContent, jansProperty, propertyAnnotation); + } + tableContents.append("\n\n"); + docContents.append((tableContents.append(detailsContent.toString()))); + createAndWriteDoc(docContents); + + } + return false; + } + + private void prepareDocTagsAndTableHeader(StringBuilder docContents, StringBuilder tableContents) { + + // add tags + docContents.append("---\n") + .append("tags:\n") + .append("- administration\n") + .append("- reference\n") + .append("- json\n") + .append("- properties\n") + .append("---\n") + .append("\n") + .append("# "+moduleName+" Configuration Properties") // add doc headers + .append("\n") + .append("\n"); + + tableContents.append("| Property Name ") // prepare table header + .append("| Description ") + .append("| | ") + .append("\n") + .append("|-----|-----|-----|") + .append("\n"); + } + + private void createAndWriteDoc(StringBuilder docContent) { + + FileObject docFile = null; + try{ + docFile = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", moduleName.toLowerCase().replaceAll("\\s", "")+"-properties.md"); + } + catch (IOException ioe){ + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, this.getClass().getName()+": Error occurred while creating annotation documentation file"); + } + if(docFile!=null){ + try(PrintWriter docWriter = new PrintWriter(docFile.openWriter());) { + docWriter.write(docContent.toString()); + docWriter.flush(); + } catch (IOException e) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, this.getClass().getName()+": Error occurred while writing annotation documentation file"); + } + } + + } + + private static void addToDetails(StringBuilder propDetails, Element jansProperty, DocProperty propertyAnnotation) { + propDetails.append("### "+ jansProperty.getSimpleName()+"\n\n"); + propDetails.append("- Description: "+ propertyAnnotation.description()+"\n\n"); + propDetails.append("- Required: "+ (propertyAnnotation.isRequired()?"Yes":"No")+"\n\n"); + propDetails.append("- Default value: "+ propertyAnnotation.defaultValue()+"\n\n"); + propDetails.append("\n"); + } + + private static void addToTable(StringBuilder propTable, Element jansProperty, DocProperty propertyAnnotation) { + propTable.append("| "+ jansProperty.getSimpleName()+" "); + propTable.append("| "+ propertyAnnotation.description()+" "); + propTable.append("| [Details](#"+jansProperty.getSimpleName().toString().toLowerCase()+") |"); + propTable.append("\n"); + } +} diff --git a/exception-extension-cdi/pom.xml b/exception-extension-cdi/pom.xml new file mode 100644 index 000000000..f0168b1c3 --- /dev/null +++ b/exception-extension-cdi/pom.xml @@ -0,0 +1,53 @@ + + + 4.0.0 + exception-extension-cdi + Reusable CDI exception handler extension + + + org.gluu + oxcore + 4.5.6-SNAPSHOT + + + + ${maven.min-version} + + + + + + src/main/resources + true + + **/*.xml + **/services/* + **/*.properties + + + + + + + + + org.slf4j + slf4j-api + provided + + + + + javax.enterprise + cdi-api + provided + + + org.jboss.weld + weld-core-impl + provided + + + + \ No newline at end of file diff --git a/oxService/src/main/java/org/gluu/service/exception/ExceptionHandler.java b/exception-extension-cdi/src/main/java/org/gluu/service/exception/ExceptionHandler.java similarity index 100% rename from oxService/src/main/java/org/gluu/service/exception/ExceptionHandler.java rename to exception-extension-cdi/src/main/java/org/gluu/service/exception/ExceptionHandler.java diff --git a/oxService/src/main/java/org/gluu/service/exception/ExceptionHandlerExtension.java b/exception-extension-cdi/src/main/java/org/gluu/service/exception/ExceptionHandlerExtension.java similarity index 97% rename from oxService/src/main/java/org/gluu/service/exception/ExceptionHandlerExtension.java rename to exception-extension-cdi/src/main/java/org/gluu/service/exception/ExceptionHandlerExtension.java index bedf2cc7e..d15e0fff9 100644 --- a/oxService/src/main/java/org/gluu/service/exception/ExceptionHandlerExtension.java +++ b/exception-extension-cdi/src/main/java/org/gluu/service/exception/ExceptionHandlerExtension.java @@ -7,6 +7,8 @@ import java.util.List; import java.util.Map; +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.context.Dependent; import javax.enterprise.event.Observes; import javax.enterprise.inject.spi.AnnotatedMethod; import javax.enterprise.inject.spi.Extension; diff --git a/oxService/src/main/java/org/gluu/service/exception/ExceptionHandlerMethods.java b/exception-extension-cdi/src/main/java/org/gluu/service/exception/ExceptionHandlerMethods.java similarity index 100% rename from oxService/src/main/java/org/gluu/service/exception/ExceptionHandlerMethods.java rename to exception-extension-cdi/src/main/java/org/gluu/service/exception/ExceptionHandlerMethods.java diff --git a/oxService/src/main/java/org/gluu/service/exception/ExceptionHandlerProducer.java b/exception-extension-cdi/src/main/java/org/gluu/service/exception/ExceptionHandlerProducer.java similarity index 100% rename from oxService/src/main/java/org/gluu/service/exception/ExceptionHandlerProducer.java rename to exception-extension-cdi/src/main/java/org/gluu/service/exception/ExceptionHandlerProducer.java diff --git a/exception-extension-cdi/src/main/resources/META-INF/beans.xml b/exception-extension-cdi/src/main/resources/META-INF/beans.xml new file mode 100644 index 000000000..2f4f7e279 --- /dev/null +++ b/exception-extension-cdi/src/main/resources/META-INF/beans.xml @@ -0,0 +1,7 @@ + + + diff --git a/oxService/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/exception-extension-cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension similarity index 54% rename from oxService/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension rename to exception-extension-cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension index a357f26bf..774c20bda 100644 --- a/oxService/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension +++ b/exception-extension-cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension @@ -1,2 +1 @@ -org.gluu.service.security.SecurityExtension org.gluu.service.exception.ExceptionHandlerExtension diff --git a/jetty-session-store-jdbc-extended/pom.xml b/jetty-session-store-jdbc-extended/pom.xml new file mode 100644 index 000000000..5338d49ff --- /dev/null +++ b/jetty-session-store-jdbc-extended/pom.xml @@ -0,0 +1,225 @@ + + + 4.0.0 + org.gluu.jetty + session-store-jdbc-extended + ${jetty-server.version} + Jetty :: Session store jdbc extended + Session store jdbc extended artifact. + + + org.gluu + oxcore + 4.5.6-SNAPSHOT + + + + 10.0.15 + https://www.eclipse.org/jetty/ + + + 11 + 11 + 11 + + false + 3.5.0 + 1.1 + 3.2.0 + 3.2.1 + 3.11.0 + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + ${maven.assembly.plugin.version} + + + org.eclipse.jetty.toolchain + jetty-assembly-descriptors + ${maven.jetty-assembly-descriptors.version} + + + + + org.apache.maven.plugins + maven-clean-plugin + ${maven.clean.plugin.version} + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven.compiler.plugin.version} + + ${compiler.source} + ${compiler.target} + ${compiler.release} + true + + -Xlint:exports + + -nowarn + + + + + + + + + + org.eclipse.jetty + jetty-bom + ${jetty-server.version} + import + pom + + + + org.eclipse.jetty + jetty-project + ${jetty-server.version} + import + pom + + + + + + + config + + + src/main/config + + + + + + org.apache.maven.plugins + maven-resources-plugin + + + copy-resources + process-resources + + copy-resources + + + UTF-8 + false + + @ + + + ${project.build.directory}/jetty-config-files + + + src/main/config + true + + **/*.p12 + + + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + config-assembly + package + + single + + + + config + + + + + + + + + + config-template + + + src/main/config-template + + + + + + org.apache.maven.plugins + maven-resources-plugin + + + copy-resources + process-resources + + copy-resources + + + UTF-8 + false + + @ + + + ${project.build.directory}/jetty-config-files + + + src/main/config-template + true + + **/*.p12 + + + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + package + + single + + + + src/main/assembly/config.xml + + + + + + + + + + + + + org.eclipse.jetty + jetty-server + + + + diff --git a/jetty-session-store-jdbc-extended/src/main/assembly/site-component.xml b/jetty-session-store-jdbc-extended/src/main/assembly/site-component.xml new file mode 100644 index 000000000..575269c1a --- /dev/null +++ b/jetty-session-store-jdbc-extended/src/main/assembly/site-component.xml @@ -0,0 +1,15 @@ + + site-component + + jar + + + + ${basedir} + jetty + + src/main/resources/org/eclipse/** + + + + diff --git a/jetty-session-store-jdbc-extended/src/main/config/etc/sessions/jdbc-extended/datasource.xml b/jetty-session-store-jdbc-extended/src/main/config/etc/sessions/jdbc-extended/datasource.xml new file mode 100644 index 000000000..be79e9577 --- /dev/null +++ b/jetty-session-store-jdbc-extended/src/main/config/etc/sessions/jdbc-extended/datasource.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/jetty-session-store-jdbc-extended/src/main/config/etc/sessions/jdbc-extended/driver.xml b/jetty-session-store-jdbc-extended/src/main/config/etc/sessions/jdbc-extended/driver.xml new file mode 100644 index 000000000..2f4c5eccf --- /dev/null +++ b/jetty-session-store-jdbc-extended/src/main/config/etc/sessions/jdbc-extended/driver.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/jetty-session-store-jdbc-extended/src/main/config/etc/sessions/jdbc-extended/session-store-extended.xml b/jetty-session-store-jdbc-extended/src/main/config/etc/sessions/jdbc-extended/session-store-extended.xml new file mode 100644 index 000000000..2a39cb4a3 --- /dev/null +++ b/jetty-session-store-jdbc-extended/src/main/config/etc/sessions/jdbc-extended/session-store-extended.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jetty-session-store-jdbc-extended/src/main/config/modules/session-store-jdbc-extended.mod b/jetty-session-store-jdbc-extended/src/main/config/modules/session-store-jdbc-extended.mod new file mode 100644 index 000000000..c345f5e78 --- /dev/null +++ b/jetty-session-store-jdbc-extended/src/main/config/modules/session-store-jdbc-extended.mod @@ -0,0 +1,75 @@ +# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + +[description] +Enables extended JDBC persistent/distributed session storage. + +[tags] +session + +[provides] +session-store-jdbc-extended + +[depend] +jdbc +sessions +sessions/jdbc-extended/${db-connection-type} + +[lib] +lib/session-store-jdbc-extended-${jetty.version}.jar + +[xml] +etc/sessions/jdbc-extended/session-store-extended.xml + +[ini] +db-connection-type?=datasource + +[ini-template] +## +##Extended JDBC Session properties +## + +#jetty.session.gracePeriod.seconds=3600 +#jetty.session.savePeriod.seconds=0 +#jetty.session.lockTime.millis=0 +#jetty.session.delayTime.millis=0 +#jetty.session.serialization.compress.data=false + +jetty.session.jdbc.blobType=mediumblob +#jetty.session.jdbc.longType= +#jetty.session.jdbc.stringType= + +## Connection type:Datasource +#db-connection-type=datasource +#jetty.session.jdbc.datasourceName=/jdbc/sessions + +## Connection type:driver +db-connection-type=driver +#jetty.session.jdbc.driverClass= +#jetty.session.jdbc.driverUrl= + +## Session table schema +#jetty.session.jdbc.schema.accessTimeColumn=accessTime +#jetty.session.jdbc.schema.contextPathColumn=contextPath +#jetty.session.jdbc.schema.cookieTimeColumn=cookieTime +#jetty.session.jdbc.schema.createTimeColumn=createTime +#jetty.session.jdbc.schema.expiryTimeColumn=expiryTime +#jetty.session.jdbc.schema.lastAccessTimeColumn=lastAccessTime +#jetty.session.jdbc.schema.lastSavedTimeColumn=lastSavedTime +#jetty.session.jdbc.schema.lockTimeColumn=lockTime +#jetty.session.jdbc.schema.idColumn=sessionId +#jetty.session.jdbc.schema.lastNodeColumn=lastNode +#jetty.session.jdbc.schema.virtualHostColumn=virtualHost +#jetty.session.jdbc.schema.maxIntervalColumn=maxInterval +#jetty.session.jdbc.schema.mapColumn=map +#jetty.session.jdbc.schema.table=JettySessions +# Optional name of the schema used to identify where the session table is defined in the database: +# "" - empty string, no schema name +# "INFERRED" - special string meaning infer from the current db connection +# name - a string defined by the user +#jetty.session.jdbc.schema.schemaName +# Optional name of the catalog used to identify where the session table is defined in the database: +# "" - empty string, no catalog name +# "INFERRED" - special string meaning infer from the current db connection +# name - a string defined by the user +#jetty.session.jdbc.schema.catalogName + diff --git a/jetty-session-store-jdbc-extended/src/main/config/modules/sessions/jdbc-extended/datasource.mod b/jetty-session-store-jdbc-extended/src/main/config/modules/sessions/jdbc-extended/datasource.mod new file mode 100644 index 000000000..50348addf --- /dev/null +++ b/jetty-session-store-jdbc-extended/src/main/config/modules/sessions/jdbc-extended/datasource.mod @@ -0,0 +1,10 @@ +# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + +[description] +JDBC Datasource connections for session storage. + +[depends] +jdbc + +[xml] +etc/sessions/jdbc-extended/datasource.xml diff --git a/jetty-session-store-jdbc-extended/src/main/config/modules/sessions/jdbc-extended/driver.mod b/jetty-session-store-jdbc-extended/src/main/config/modules/sessions/jdbc-extended/driver.mod new file mode 100644 index 000000000..2e2ee9fa0 --- /dev/null +++ b/jetty-session-store-jdbc-extended/src/main/config/modules/sessions/jdbc-extended/driver.mod @@ -0,0 +1,10 @@ +# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + +[description] +JDBC Driver connections for session storage. + +[depend] +jdbc + +[xml] +etc/sessions/jdbc-extended/driver.xml diff --git a/jetty-session-store-jdbc-extended/src/main/java/module-info.java b/jetty-session-store-jdbc-extended/src/main/java/module-info.java new file mode 100644 index 000000000..41748e358 --- /dev/null +++ b/jetty-session-store-jdbc-extended/src/main/java/module-info.java @@ -0,0 +1,24 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +module org.eclipse.jetty.server.session.extended +{ + requires transitive jetty.servlet.api; + requires transitive org.eclipse.jetty.server; + requires transitive org.slf4j; + + // Only required if using DatabaseAdaptor/JDBCSessionDataStore. + requires static java.sql; + + exports org.eclipse.jetty.server.session.extended; +} diff --git a/jetty-session-store-jdbc-extended/src/main/java/org/eclipse/jetty/server/session/extended/DatabaseAdaptor.java b/jetty-session-store-jdbc-extended/src/main/java/org/eclipse/jetty/server/session/extended/DatabaseAdaptor.java new file mode 100644 index 000000000..682b0a243 --- /dev/null +++ b/jetty-session-store-jdbc-extended/src/main/java/org/eclipse/jetty/server/session/extended/DatabaseAdaptor.java @@ -0,0 +1,13 @@ +package org.eclipse.jetty.server.session.extended; + +import java.sql.Connection; +import java.sql.SQLException; + +public class DatabaseAdaptor extends org.eclipse.jetty.server.session.DatabaseAdaptor { + + @Override + protected Connection getConnection() throws SQLException { + return super.getConnection(); + } + +} diff --git a/jetty-session-store-jdbc-extended/src/main/java/org/eclipse/jetty/server/session/extended/ExtendedObjectOutputStream.java b/jetty-session-store-jdbc-extended/src/main/java/org/eclipse/jetty/server/session/extended/ExtendedObjectOutputStream.java new file mode 100644 index 000000000..04b40c08f --- /dev/null +++ b/jetty-session-store-jdbc-extended/src/main/java/org/eclipse/jetty/server/session/extended/ExtendedObjectOutputStream.java @@ -0,0 +1,28 @@ +package org.eclipse.jetty.server.session.extended; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.Serializable; + +public class ExtendedObjectOutputStream extends java.io.ObjectOutputStream { + + public ExtendedObjectOutputStream(OutputStream out) throws IOException { + super(out); + enableReplaceObject(true); + } + + @Override + protected Object replaceObject(Object obj) throws IOException { + if (obj instanceof Serializable) { + return obj; + } + + return null; + } + + public class NullOutputStream extends OutputStream { + @Override + public void write(int b) throws IOException {} + } + +} diff --git a/jetty-session-store-jdbc-extended/src/main/java/org/eclipse/jetty/server/session/extended/JDBCExtendedSessionDataStore.java b/jetty-session-store-jdbc-extended/src/main/java/org/eclipse/jetty/server/session/extended/JDBCExtendedSessionDataStore.java new file mode 100644 index 000000000..f33f3d25b --- /dev/null +++ b/jetty-session-store-jdbc-extended/src/main/java/org/eclipse/jetty/server/session/extended/JDBCExtendedSessionDataStore.java @@ -0,0 +1,476 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.server.session.extended; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectOutputStream; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; +import java.util.Base64; +import java.util.HashMap; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +import org.eclipse.jetty.server.session.JDBCSessionDataStore; +import org.eclipse.jetty.server.session.SessionContext; +import org.eclipse.jetty.server.session.SessionData; +import org.eclipse.jetty.server.session.UnreadableSessionDataException; +import org.eclipse.jetty.util.ClassLoadingObjectInputStream; +import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.util.annotation.ManagedAttribute; +import org.eclipse.jetty.util.annotation.ManagedObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * JDBCExtendedSessionDataStore + * + * Session data stored in database + */ +@ManagedObject +public class JDBCExtendedSessionDataStore extends JDBCSessionDataStore +{ + private static final Logger LOG = LoggerFactory.getLogger(JDBCExtendedSessionDataStore.class); + + private int _lockPeriodMillis; + private int _delayPeriodMillis; + private boolean _compressSerializedData = false; + + /** + * SessionTableSchema + */ + public static class SessionTableSchema extends org.eclipse.jetty.server.session.JDBCSessionDataStore.SessionTableSchema + { + protected String _lockTimeColumn = "lockTime"; + + protected void setDatabaseAdaptor(DatabaseAdaptor dbadaptor) + { + _dbAdaptor = dbadaptor; + } + + public void setLockTimeColumn(String lockTimeColumn) + { + checkNotNull(lockTimeColumn); + _lockTimeColumn = lockTimeColumn; + } + + public String getLockTimeColumn() + { + return _lockTimeColumn; + } + + private void checkNotNull(String s) + { + if (s == null) + throw new IllegalArgumentException(s); + } + + private String getSchemaTableName() + { + return (getSchemaName() != null ? getSchemaName() + "." : "") + getTableName(); + } + + /* + * Added lockTableColumn creation + */ + public String getCreateStatementAsString() + { + if (_dbAdaptor == null) + throw new IllegalStateException("No DBAdaptor"); + + String blobType = _dbAdaptor.getBlobType(); + String longType = _dbAdaptor.getLongType(); + String stringType = _dbAdaptor.getStringType(); + + return "create table " + getSchemaTableName() + " (" + _idColumn + " " + stringType + "(120), " + + _contextPathColumn + " " + stringType + "(60), " + _virtualHostColumn + " " + stringType + "(60), " + _lastNodeColumn + " " + stringType + "(60), " + _accessTimeColumn + " " + longType + ", " + + _lastAccessTimeColumn + " " + longType + ", " + _createTimeColumn + " " + longType + ", " + _cookieTimeColumn + " " + longType + ", " + + _lastSavedTimeColumn + " " + longType + ", " + _expiryTimeColumn + " " + longType + ", " + _maxIntervalColumn + " " + longType + ", " + _lockTimeColumn + " " + longType + ", " + + _mapColumn + " " + blobType + ", primary key(" + _idColumn + ", " + _contextPathColumn + "," + _virtualHostColumn + "))"; + } + + /* + * Added lockTableColumn value set + */ + @Override + public String getInsertSessionStatementAsString() + { + return "insert into " + getSchemaTableName() + + " (" + getIdColumn() + ", " + getContextPathColumn() + ", " + getVirtualHostColumn() + ", " + getLastNodeColumn() + + ", " + getAccessTimeColumn() + ", " + getLastAccessTimeColumn() + ", " + getCreateTimeColumn() + ", " + getCookieTimeColumn() + + ", " + getLastSavedTimeColumn() + ", " + getExpiryTimeColumn() + ", " + getMaxIntervalColumn() + ", " + getLockTimeColumn() + ", " + getMapColumn() + ") " + + " values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + } + + /* + * Added lockTableColumn value clear + */ + @Override + public PreparedStatement getUpdateSessionStatement(Connection connection, String id, SessionContext context) + throws SQLException + { + String s = "update " + getSchemaTableName() + + " set " + getLastNodeColumn() + " = ?, " + getAccessTimeColumn() + " = ?, " + + getLastAccessTimeColumn() + " = ?, " + getLastSavedTimeColumn() + " = ?, " + getExpiryTimeColumn() + " = ?, " + + getMaxIntervalColumn() + " = ?, " + getLockTimeColumn() + " = ?, " + getMapColumn() + " = ? where " + getIdColumn() + " = ? and " + getContextPathColumn() + + " = ? and " + getVirtualHostColumn() + " = ?"; + + String cp = context.getCanonicalContextPath(); + if (_dbAdaptor.isEmptyStringNull() && StringUtil.isBlank(cp)) + cp = NULL_CONTEXT_PATH; + + PreparedStatement statement = connection.prepareStatement(s); + statement.setString(9, id); + statement.setString(10, cp); + statement.setString(11, context.getVhost()); + return statement; + } + + @Override + public String toString() + { + return String.format("%s[%s]", super.toString(), _lockTimeColumn); + } + } + + /* + * Quickly insert with lockTime. After that do update with session data + */ + @Override + protected void doInsert(String id, SessionData data) + throws Exception + { + if (LOG.isDebugEnabled()) { + LOG.debug(">>>>>>>>>> INSERT START: {}", id); + } + boolean useLock = _lockPeriodMillis > 0; + String s = _sessionTableSchema.getInsertSessionStatementAsString(); + + try (Connection connection = ((org.eclipse.jetty.server.session.extended.DatabaseAdaptor) _dbAdaptor).getConnection()) + { + connection.setAutoCommit(true); + try (PreparedStatement statement = connection.prepareStatement(s)) + { + statement.setString(1, id); //session id + + String cp = _context.getCanonicalContextPath(); + if (_dbAdaptor.isEmptyStringNull() && StringUtil.isBlank(cp)) + cp = NULL_CONTEXT_PATH; + + statement.setString(2, cp); //context path + + statement.setString(3, _context.getVhost()); //first vhost + statement.setString(4, data.getLastNode()); //my node id + statement.setLong(5, data.getAccessed()); //accessTime + statement.setLong(6, data.getLastAccessed()); //lastAccessTime + statement.setLong(7, data.getCreated()); //time created + statement.setLong(8, data.getCookieSet()); //time cookie was set + statement.setLong(9, data.getLastSaved()); //last saved time + statement.setLong(10, data.getExpiry()); + statement.setLong(11, data.getMaxInactiveMs()); + statement.setLong(12, System.currentTimeMillis()); // lockTime + + try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ExtendedObjectOutputStream(baos)) + { + if (useLock) { + // Write empty legacy object to speed up initial record insert + oos.writeObject(new HashMap()); + } else { + SessionData.serializeAttributes(data, oos); + } + byte[] bytes = baos.toByteArray(); + if (LOG.isDebugEnabled()) { + LOG.debug("SessionData dump in INSERT for Vhost {} in base64: {}", _context.getVhost(), Base64.getEncoder().encodeToString(bytes)); + } + + if (_compressSerializedData) { + try (ByteArrayOutputStream baos2 = new ByteArrayOutputStream(); + GZIPOutputStream gos = new GZIPOutputStream(baos2)) { + gos.write(bytes); + gos.finish(); + bytes = baos2.toByteArray(); + } + } + try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes)) + { + statement.setBinaryStream(13, bais, bytes.length); //attribute map as blob + } + } + + statement.executeUpdate(); + if (LOG.isDebugEnabled()) + LOG.debug("Inserted session {}", data); + } + } + if (LOG.isDebugEnabled()) { + LOG.debug("<<<<<<<<<< INSERT END: {}", id); + } + + if (useLock) { + // Save with serialized data + doUpdate(id, data); + } + } + + @Override + protected void doUpdate(String id, SessionData data) + throws Exception + { + if (LOG.isDebugEnabled()) { + LOG.debug(">>>>>>>>>> UPDATE START: {}", id); + } + try (Connection connection = ((org.eclipse.jetty.server.session.extended.DatabaseAdaptor) _dbAdaptor).getConnection()) + { + connection.setAutoCommit(true); + try (PreparedStatement statement = _sessionTableSchema.getUpdateSessionStatement(connection, data.getId(), _context)) + { + statement.setString(1, data.getLastNode()); //should be my node id + statement.setLong(2, data.getAccessed()); //accessTime + statement.setLong(3, data.getLastAccessed()); //lastAccessTime + statement.setLong(4, data.getLastSaved()); //last saved time + statement.setLong(5, data.getExpiry()); + statement.setLong(6, data.getMaxInactiveMs()); + statement.setNull(7, Types.BIGINT); + + try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ExtendedObjectOutputStream(baos)) + { + SessionData.serializeAttributes(data, oos); + byte[] bytes = baos.toByteArray(); + if (LOG.isDebugEnabled()) { + LOG.debug("SessionData dump in UPDATE for Vhost {} in base64: {}", _context.getVhost(), Base64.getEncoder().encodeToString(bytes)); + } + + if (_compressSerializedData) { + try (ByteArrayOutputStream baos2 = new ByteArrayOutputStream(); + GZIPOutputStream gos = new GZIPOutputStream(baos2)) { + gos.write(bytes); + gos.finish(); + bytes = baos2.toByteArray(); + } + } + try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes)) + { + statement.setBinaryStream(8, bais, bytes.length); //attribute map as blob + } + } + + statement.executeUpdate(); + + if (LOG.isDebugEnabled()) + LOG.debug("Updated session {}", data); + } + } + if (LOG.isDebugEnabled()) { + LOG.debug("<<<<<<<<<< UPDATE END: {}", id); + } + } + + @Override + public SessionData doLoad(String id) throws Exception + { + if (LOG.isDebugEnabled()) { + LOG.debug(">>>>>>>>>> LOAD START: {}", id); + } + ExtendedSessionData extendedSessionData = doLoadImpl(id, true); + if (extendedSessionData.getLockTime() == null) { + return extendedSessionData.getSessionData(); + } + + // Wait specified milliseconds and try to load again + long unlockTime = extendedSessionData.getLockTime() + _lockPeriodMillis; + long currTime = System.currentTimeMillis(); + long sleepTime = unlockTime - currTime; + if (sleepTime > 0) { + if (LOG.isDebugEnabled()) { + LOG.debug("<<<<<<<<<< LOAD START DELAY FOR LOCK: {}", id); + } + Thread.sleep(sleepTime); + if (LOG.isDebugEnabled()) { + LOG.debug(">>>>>>>>>> LOAD END DELAY FOR LOCK: {}", id); + } + } + + // Load after lock expiration + extendedSessionData = doLoadImpl(id, false); + + if (LOG.isDebugEnabled()) { + LOG.debug("<<<<<<<<<< LOAD END: {}", id); + } + return extendedSessionData.getSessionData(); + } + + protected ExtendedSessionData doLoadImpl(String id, boolean checkLock) throws Exception + { + if (LOG.isDebugEnabled()) { + LOG.debug("---------- LOAD IMPL: {} : {}", id, checkLock); + } + try (Connection connection = ((org.eclipse.jetty.server.session.extended.DatabaseAdaptor) _dbAdaptor).getConnection(); + PreparedStatement statement = _sessionTableSchema.getLoadStatement(connection, id, _context); + ResultSet result = statement.executeQuery()) + { + SessionData data = null; + Long lockTime = null; + if (result.next()) + { + data = newSessionData(id, + result.getLong(_sessionTableSchema.getCreateTimeColumn()), + result.getLong(_sessionTableSchema.getAccessTimeColumn()), + result.getLong(_sessionTableSchema.getLastAccessTimeColumn()), + result.getLong(_sessionTableSchema.getMaxIntervalColumn())); + data.setCookieSet(result.getLong(_sessionTableSchema.getCookieTimeColumn())); + data.setLastNode(result.getString(_sessionTableSchema.getLastNodeColumn())); + data.setLastSaved(result.getLong(_sessionTableSchema.getLastSavedTimeColumn())); + data.setExpiry(result.getLong(_sessionTableSchema.getExpiryTimeColumn())); + data.setContextPath(_context.getCanonicalContextPath()); + data.setVhost(_context.getVhost()); + + lockTime = result.getLong(((org.eclipse.jetty.server.session.extended.JDBCExtendedSessionDataStore.SessionTableSchema) _sessionTableSchema).getLockTimeColumn()); + + // Check lock if needed + if (checkLock && !isLockExpired(lockTime)) { + return new ExtendedSessionData(data, lockTime); + } + + InputStream is2 = _dbAdaptor.getBlobInputStream(result, _sessionTableSchema.getMapColumn()); + + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + int nRead; + byte[] buf = new byte[16384]; + + while ((nRead = is2.read(buf, 0, buf.length)) != -1) { + buffer.write(buf, 0, nRead); + } + + if (LOG.isDebugEnabled()) { + LOG.debug("Data for deserialization in base64: {}", Base64.getEncoder().encodeToString(buffer.toByteArray())); + } + + try (InputStream is = getBlobInputStream(result); + ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(is)) + { + if (LOG.isDebugEnabled()) { + LOG.debug(">>>>>>>>>> DESERIALIZATION START: {}", id); + } + if (_delayPeriodMillis > 0) { + if (LOG.isDebugEnabled()) { + LOG.debug(">>>>>>>>>> DESERIALIZATION DELAY: {}", id); + } + Thread.sleep(_delayPeriodMillis); + if (LOG.isDebugEnabled()) { + LOG.debug("<<<<<<<<<< DESERIALIZATION RESUME: {}", id); + } + } + SessionData.deserializeAttributes(data, ois); + if (LOG.isDebugEnabled()) { + LOG.debug("<<<<<<<<<< DESERIALIZATION END: {}", id); + } + } + catch (Exception e) + { + throw new UnreadableSessionDataException(id, _context, e); + } + + if (LOG.isDebugEnabled()) + LOG.debug("LOADED session {}", data); + } + else if (LOG.isDebugEnabled()) { + LOG.debug("No session {}", id); + } + + return new ExtendedSessionData(data, null); + } + } + + private InputStream getBlobInputStream(ResultSet resultSet) throws SQLException, IOException { + InputStream resultStream =_dbAdaptor.getBlobInputStream(resultSet, _sessionTableSchema.getMapColumn()); + if (_compressSerializedData) { + LOG.info("USING COMPRESSION"); + try (InputStream gis = new GZIPInputStream(resultStream)) { + resultStream = new ByteArrayInputStream(gis.readAllBytes()); + } + } + + return resultStream; + } + + private boolean isLockExpired(Long lockTime) { + if (lockTime == null) { + return true; + } + + long unlockTime = lockTime + _lockPeriodMillis; + long currTime = System.currentTimeMillis(); + + return unlockTime < currTime; + } + + public static class ExtendedSessionData { + private final SessionData sessionData; + private final Long lockTime; + + public ExtendedSessionData(SessionData sessionData, Long lockTime) { + this.sessionData = sessionData; + this.lockTime = lockTime; + } + + public SessionData getSessionData() { + return sessionData; + } + + public Long getLockTime() { + return lockTime; + } + + } + + @ManagedAttribute(value = "interval in millis to wait for session record lock", readonly = true) + public int getLockPeriodMillis() + { + return _lockPeriodMillis; + } + + public void setLockPeriodMillis(int millis) + { + _lockPeriodMillis = millis; + } + + @ManagedAttribute(value = "interval in millis to wait before session deserialization", readonly = true) + public int getDelayPeriodMillis() + { + return _delayPeriodMillis; + } + + public void setDelayPeriodMillis(int millis) + { + _delayPeriodMillis = millis; + } + + @ManagedAttribute(value = "specify if serialized data should be compressed", readonly = true) + public boolean getCompressSerializedData() { + return _compressSerializedData; + } + + public void setCompressSerializedData(boolean compressSerializedData) { + _compressSerializedData = compressSerializedData; + } + +} diff --git a/jetty-session-store-jdbc-extended/src/main/java/org/eclipse/jetty/server/session/extended/JDBCExtendedSessionDataStoreFactory.java b/jetty-session-store-jdbc-extended/src/main/java/org/eclipse/jetty/server/session/extended/JDBCExtendedSessionDataStoreFactory.java new file mode 100644 index 000000000..e73f7d40f --- /dev/null +++ b/jetty-session-store-jdbc-extended/src/main/java/org/eclipse/jetty/server/session/extended/JDBCExtendedSessionDataStoreFactory.java @@ -0,0 +1,95 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.server.session.extended; + +import org.eclipse.jetty.server.session.DatabaseAdaptor; +import org.eclipse.jetty.server.session.JDBCSessionDataStore; +import org.eclipse.jetty.server.session.JDBCSessionDataStoreFactory; +import org.eclipse.jetty.server.session.SessionDataStore; +import org.eclipse.jetty.server.session.SessionHandler; + +/** + * JDBCExtendedSessionDataStoreFactory + */ +public class JDBCExtendedSessionDataStoreFactory extends JDBCSessionDataStoreFactory +{ + + public static final int DEFAULT_LOCK_PERIOD_MILLIS = 0; //default of 0 millis + public static final int DEFAULT_DELAY_PERIOD_MILLIS = 0; //default of 0 millis + + DatabaseAdaptor _adaptor; + + JDBCSessionDataStore.SessionTableSchema _schema; + + private int _lockPeriodMillis = DEFAULT_LOCK_PERIOD_MILLIS; + private int _delayPeriodMillis = DEFAULT_DELAY_PERIOD_MILLIS; + private boolean _compressSerializedData = false; + + @Override + public SessionDataStore getSessionDataStore(SessionHandler handler) + { + JDBCExtendedSessionDataStore ds = new JDBCExtendedSessionDataStore(); + ds.setDatabaseAdaptor(_adaptor); + ds.setSessionTableSchema(_schema); + ds.setGracePeriodSec(getGracePeriodSec()); + ds.setSavePeriodSec(getSavePeriodSec()); + + ds.setLockPeriodMillis(_lockPeriodMillis); + ds.setDelayPeriodMillis(_delayPeriodMillis); + ds.setCompressSerializedData(_compressSerializedData); + return ds; + } + + /** + * @param adaptor the {@link DatabaseAdaptor} to set + */ + public void setDatabaseAdaptor(DatabaseAdaptor adaptor) + { + _adaptor = adaptor; + } + + /** + * @param schema the {@link JDBCSessionDataStoreFactory} to set + */ + public void setSessionTableSchema(JDBCSessionDataStore.SessionTableSchema schema) + { + _schema = schema; + } + + public int getLockPeriodMillis() + { + return _lockPeriodMillis; + } + + public void setLockPeriodMillis(int millis) + { + _lockPeriodMillis = millis; + } + + public int getDelayPeriodMillis() { + return _delayPeriodMillis; + } + + public void setDelayPeriodMillis(int millis) { + this._delayPeriodMillis = millis; + } + + public boolean getCompressSerializedData() { + return _compressSerializedData; + } + + public void setCompressSerializedData(boolean compressSerializedData) { + _compressSerializedData = compressSerializedData; + } +} diff --git a/oxJsfUtil/pom.xml b/oxJsfUtil/pom.xml index ff53e0e29..3f7a1ce96 100644 --- a/oxJsfUtil/pom.xml +++ b/oxJsfUtil/pom.xml @@ -1,62 +1,66 @@ - - - 4.0.0 - oxcore-jsf-util - jar - oxJsfUtil - JSF2 utilities - - - org.gluu - oxcore - 4.0.0-SNAPSHOT - - - - - - src/main/resources - true - - **/*.xml - **/services/* - **/*.properties - - - - - - - - org.gluu - oxcore-service - ${project.version} - - - javax.enterprise - cdi-api - provided - - - com.sun.faces - jsf-api - provided - - - javax.servlet - javax.servlet-api - provided - - - javax.el - el-api - provided - - - org.glassfish - javax.faces - - - + + + 4.0.0 + oxcore-jsf-util + jar + oxJsfUtil + JSF2 utilities + + + org.gluu + oxcore + 4.5.6-SNAPSHOT + + + + + + src/main/resources + true + + **/*.xml + **/services/* + **/*.properties + + + + + + + + org.gluu + oxcore-service + + + javax.enterprise + cdi-api + provided + + + com.sun.faces + jsf-api + provided + + + org.glassfish + jakarta.faces + + + javax.servlet + javax.servlet-api + provided + + + javax.el + el-api + provided + + + org.glassfish.web + el-impl + provided + + + \ No newline at end of file diff --git a/oxJsfUtil/src/main/java/org/gluu/jsf2/customization/FacesConfigPopulator.java b/oxJsfUtil/src/main/java/org/gluu/jsf2/customization/FacesConfigPopulator.java index d169eb568..04b4a38fe 100644 --- a/oxJsfUtil/src/main/java/org/gluu/jsf2/customization/FacesConfigPopulator.java +++ b/oxJsfUtil/src/main/java/org/gluu/jsf2/customization/FacesConfigPopulator.java @@ -1,7 +1,15 @@ package org.gluu.jsf2.customization; -import com.sun.faces.config.DbfFactory; -import com.sun.faces.util.FacesLogger; +import java.io.File; +import java.net.URL; +import java.util.Collection; +import java.util.Enumeration; +import java.util.logging.Level; + +import javax.faces.application.ApplicationConfigurationPopulator; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + import org.apache.commons.io.FileUtils; import org.apache.commons.io.filefilter.DirectoryFileFilter; import org.apache.commons.io.filefilter.RegexFileFilter; @@ -11,142 +19,103 @@ import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; -import org.w3c.dom.ls.LSResourceResolver; -import javax.faces.application.ApplicationConfigurationPopulator; -import javax.xml.XMLConstants; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.transform.stream.StreamSource; -import javax.xml.validation.Schema; -import javax.xml.validation.SchemaFactory; -import javax.xml.validation.Validator; -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; -import java.net.URL; -import java.util.Collection; -import java.util.Enumeration; -import java.util.logging.Level; +import com.sun.faces.util.FacesLogger; /** * Created by eugeniuparvan on 5/1/17. */ public class FacesConfigPopulator extends ApplicationConfigurationPopulator { - /** - *

/faces-config/navigation-rule

- */ - private static final String NAVIGATION_RULE = "navigation-rule"; - private static final String FACES_2_2_XSD = "/com/sun/faces/web-facesconfig_2_2.xsd"; - private static final String FACES_CONFIG_PATTERN = ".*\\.navigation\\.xml$"; - private static final String DEFAULT_NAVIGATION_PATH = "META-INF/navigation"; - - private Logger log = LoggerFactory.getLogger(FacesConfigPopulator.class); - - @Override - public void populateApplicationConfiguration(Document toPopulate) { - log.debug("Starting configuration populator"); - - if (Utils.isCustomPagesDirExists()) { - String customPath = Utils.getCustomPagesPath(); - log.debug("Adding navigation rules from custom dir folder: {}", customPath); - try { - findAndUpdateNavigationRules(toPopulate, customPath); - } catch (Exception ex) { - FacesLogger.CONFIG.getLogger().log(Level.SEVERE, "Can't add customized navigation rules"); - } - } - - try { - log.debug("Adding navigation rules from application resurces"); - Enumeration urlEnumeration = getClass().getClassLoader().getResources(DEFAULT_NAVIGATION_PATH); - if (urlEnumeration.hasMoreElements()) { - URL url = urlEnumeration.nextElement(); - findAndUpdateNavigationRules(toPopulate, url.getPath()); - } - } catch (Exception ex) { - log.error("Failed to populate application configuraton", ex); - } - } - - /** - * Recursively finds all *.navigation.xml files located in custom pages directory, and adds navigation rules to - * navigation handler - * - * @param path to custom pages directory - * @throws Exception - */ - private void findAndUpdateNavigationRules(Document toPopulate, String path) throws Exception { - File file = new File(path); - RegexFileFilter regexFileFilter = new RegexFileFilter(FACES_CONFIG_PATTERN); - Collection facesConfigFiles = FileUtils.listFiles(file, regexFileFilter, DirectoryFileFilter.DIRECTORY); - log.debug("Found '{}' navigation rules files", facesConfigFiles.size()); - - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - factory.setNamespaceAware(true); - DocumentBuilder builder = factory.newDocumentBuilder(); - - for (File files : facesConfigFiles) { - String faceConfig = files.getAbsolutePath(); - updateDocument(toPopulate, builder, faceConfig); - log.debug("Added navigation rules from {}", faceConfig); - } - } - - /** - * Validates *.faces-config.xml file and creates DocumentInfo class - * - * @param docBuilder - * @param faceConfig - * @return - */ - private void updateDocument(Document toPopulate, DocumentBuilder docBuilder, String faceConfig) { - try { - InputStream xml = new FileInputStream(faceConfig); -// try { -// if (!isValidFacesConfig(xml)) { -// return; -// } -// } finally { -// xml.close(); -// } - Document document = docBuilder.parse(new File(faceConfig)); - Element root = toPopulate.getDocumentElement(); - NodeList navigationRules = getNavigationRules(document); - for (int i = 0; i < navigationRules.getLength(); ++i) { - Node importedNode = toPopulate.importNode(navigationRules.item(i), true); - root.appendChild(importedNode); - } - } catch (Exception ex) { - log.error("Failed to update navigation rules", ex); - } - } - - /** - * Validates *.faces-config.xml file - * - * @param xml - * @return - */ - private boolean isValidFacesConfig(InputStream xml) { - try { - SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); - factory.setResourceResolver((LSResourceResolver) DbfFactory.FACES_ENTITY_RESOLVER); - - InputStream xsd = this.getClass().getResourceAsStream(FACES_2_2_XSD); - Schema schema = factory.newSchema(new StreamSource(xsd)); - - Validator validator = schema.newValidator(); - validator.validate(new StreamSource(xml)); - return true; - } catch (Exception ex) { - return false; - } - } - - private NodeList getNavigationRules(Document document) { - String namespace = document.getDocumentElement() - .getNamespaceURI(); - return document.getDocumentElement().getElementsByTagNameNS(namespace, NAVIGATION_RULE); - } + /** + *

+ * /faces-config/navigation-rule + *

+ */ + private static final String NAVIGATION_RULE = "navigation-rule"; + private static final String FACES_CONFIG_PATTERN = ".*\\.navigation\\.xml$"; + private static final String DEFAULT_NAVIGATION_PATH = "META-INF/navigation"; + + private Logger log = LoggerFactory.getLogger(FacesConfigPopulator.class); + + @Override + public void populateApplicationConfiguration(Document toPopulate) { + populateNavigationRules(toPopulate); + } + + // Navigation Rules + protected void populateNavigationRules(Document toPopulate) { + log.debug("Starting configuration populator"); + + if (Utils.isCustomPagesDirExists()) { + String customPath = Utils.getCustomPagesPath(); + log.debug("Adding navigation rules from custom dir folder: {}", customPath); + try { + findAndUpdateNavigationRules(toPopulate, customPath); + } catch (Exception ex) { + FacesLogger.CONFIG.getLogger().log(Level.SEVERE, "Can't add customized navigation rules"); + } + } + + try { + log.debug("Adding navigation rules from application resurces"); + Enumeration urlEnumeration = getClass().getClassLoader().getResources(DEFAULT_NAVIGATION_PATH); + if (urlEnumeration.hasMoreElements()) { + URL url = urlEnumeration.nextElement(); + findAndUpdateNavigationRules(toPopulate, url.getPath()); + } + } catch (Exception ex) { + log.error("Failed to populate application configuraton", ex); + } + } + + /** + * Recursively finds all *.navigation.xml files located in custom pages + * directory, and adds navigation rules to navigation handler + * + * @param path to custom pages directory + * @throws Exception + */ + private void findAndUpdateNavigationRules(Document toPopulate, String path) throws Exception { + File file = new File(path); + RegexFileFilter regexFileFilter = new RegexFileFilter(FACES_CONFIG_PATTERN); + Collection facesConfigFiles = FileUtils.listFiles(file, regexFileFilter, DirectoryFileFilter.DIRECTORY); + log.debug("Found '{}' navigation rules files", facesConfigFiles.size()); + + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + DocumentBuilder builder = factory.newDocumentBuilder(); + + for (File files : facesConfigFiles) { + String faceConfig = files.getAbsolutePath(); + updateDocument(toPopulate, builder, faceConfig); + log.debug("Added navigation rules from {}", faceConfig); + } + } + + /** + * Validates *.faces-config.xml file and creates DocumentInfo class + * + * @param docBuilder + * @param faceConfig + * @return + */ + private void updateDocument(Document toPopulate, DocumentBuilder docBuilder, String faceConfig) { + try { + Document document = docBuilder.parse(new File(faceConfig)); + Element root = toPopulate.getDocumentElement(); + NodeList navigationRules = getNavigationRules(document); + for (int i = 0; i < navigationRules.getLength(); ++i) { + Node importedNode = toPopulate.importNode(navigationRules.item(i), true); + root.appendChild(importedNode); + } + } catch (Exception ex) { + log.error("Failed to update navigation rules", ex); + } + } + + private NodeList getNavigationRules(Document document) { + String namespace = document.getDocumentElement().getNamespaceURI(); + return document.getDocumentElement().getElementsByTagNameNS(namespace, NAVIGATION_RULE); + } + } diff --git a/oxJsfUtil/src/main/java/org/gluu/jsf2/customization/FacesLocalizationConfigPopulator.java b/oxJsfUtil/src/main/java/org/gluu/jsf2/customization/FacesLocalizationConfigPopulator.java new file mode 100644 index 000000000..3d517444d --- /dev/null +++ b/oxJsfUtil/src/main/java/org/gluu/jsf2/customization/FacesLocalizationConfigPopulator.java @@ -0,0 +1,139 @@ +package org.gluu.jsf2.customization; + +import java.io.File; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.logging.Level; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.faces.application.ApplicationConfigurationPopulator; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.filefilter.DirectoryFileFilter; +import org.apache.commons.io.filefilter.RegexFileFilter; +import org.gluu.util.StringHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.sun.faces.util.FacesLogger; + +/** + * @author Yuriy Movchan + * @version 06/11/2020 + */ +public abstract class FacesLocalizationConfigPopulator extends ApplicationConfigurationPopulator { + + private static final String DEFAULT_LANGUAGE_PATH = "/classes/"; + + private Logger log = LoggerFactory.getLogger(FacesLocalizationConfigPopulator.class); + + @Override + public void populateApplicationConfiguration(Document toPopulate) { + populateLocalizations(toPopulate); + } + + private void populateLocalizations(Document toPopulate) { + log.debug("Starting localization configuration populator"); + + if (Utils.isCustomLocalizationDirExists()) { + String customLocalizationPath = Utils.getCustomLocalizationPath(); + log.debug("Adding localizations from custom dir folder: {}", customLocalizationPath); + try { + findAndAddLocalizations(toPopulate, customLocalizationPath); + } catch (Exception ex) { + FacesLogger.CONFIG.getLogger().log(Level.SEVERE, "Can't add localizations from custom dir"); + } + } + + try { + log.debug("Adding localizations from application resurces"); + URL[] ulrs = ((URLClassLoader) (Thread.currentThread().getContextClassLoader())).getURLs(); + for (URL url : ulrs) { + if (url.getFile().endsWith(DEFAULT_LANGUAGE_PATH)) { + int count = findAndAddLocalizations(toPopulate, url.getFile()); + if (count > 0) { + log.debug("Added {} application localizations from war folder: {}", count, url.getFile()); + } + } + } + } catch (Exception ex) { + log.error("Failed to populate application localizations", ex); + } + } + + private int findAndAddLocalizations(Document toPopulate, String path) throws Exception { + String languageFilePattern = getLanguageFilePattern(); + RegexFileFilter regexFileFilter = new RegexFileFilter(languageFilePattern); + Pattern regexFilePatern = Pattern.compile(languageFilePattern); + + File file = new File(path); + Collection languageFiles = FileUtils.listFiles(file, regexFileFilter, DirectoryFileFilter.DIRECTORY); + + if (languageFiles.size() == 0) { + return 0; + } + log.debug("Found '{}' language files", languageFiles.size()); + + List localeNames = new ArrayList(); + for (File languageFile : languageFiles) { + Matcher matcher = regexFilePatern.matcher(languageFile.getName()); + + if (matcher.matches()) { + String localeName = matcher.group(1); + + localeNames.add(localeName); + } + } + log.info("Adding languages '{}' from dir folder: {}", localeNames, path); + + updateDocument(toPopulate, localeNames); + + return localeNames.size(); + } + + private void updateDocument(Document toPopulate, List localeNames) { + String ns = toPopulate.getDocumentElement().getNamespaceURI(); + Element rootElement = toPopulate.getDocumentElement(); + + // Add application + Node applicationNode = getChildOrCreate(toPopulate, ns, rootElement, "application"); + + // Add locale-config + Node localeConfigNode = getChildOrCreate(toPopulate, ns, applicationNode, "locale-config"); + + for (String localeName : localeNames) { + // Add supported-locale + Element supportedLocaleElement = toPopulate.createElementNS(ns, "supported-locale"); + Node supportedLocaleNode = localeConfigNode.appendChild(supportedLocaleElement); + + supportedLocaleNode.appendChild(toPopulate.createTextNode(localeName)); + } + } + + protected Node getChildOrCreate(Document toPopulate, String ns, Node rootElement, String childNodeName) { + if (rootElement.hasChildNodes()) { + NodeList nodeList = rootElement.getChildNodes(); + for (int i = 0; i < nodeList.getLength(); i++) { + if (StringHelper.equals(nodeList.item(i).getNodeName(), childNodeName)) { + return nodeList.item(i); + } + } + } + + Element applicationElement = toPopulate.createElementNS(ns, childNodeName); + Node applicationNode = rootElement.appendChild(applicationElement); + + return applicationNode; + } + + public abstract String getLanguageFilePattern(); + +} diff --git a/oxJsfUtil/src/main/java/org/gluu/jsf2/customization/Utils.java b/oxJsfUtil/src/main/java/org/gluu/jsf2/customization/Utils.java index 03b6b54bd..1ea303a9c 100644 --- a/oxJsfUtil/src/main/java/org/gluu/jsf2/customization/Utils.java +++ b/oxJsfUtil/src/main/java/org/gluu/jsf2/customization/Utils.java @@ -10,6 +10,7 @@ public final class Utils { private static final String SERVER_BASE_PATH = "server.base"; private static final String CUSTOM_PAGES_PATH = "/custom/pages"; + private static final String CUSTOM_LOCALIZATION_PATH = "/custom/i18n"; private Utils() { } @@ -25,6 +26,18 @@ public static boolean isCustomPagesDirExists() { } } + public static boolean isCustomLocalizationDirExists() { + String externalResourceBase = getCustomLocalizationPath(); + if (StringHelper.isNotEmpty(externalResourceBase)) { + File folder = new File(externalResourceBase); + boolean result = folder.exists() && folder.isDirectory(); + + return result; + } else { + return false; + } + } + public static String getCustomPagesPath() { String externalResourceBase = System.getProperty(SERVER_BASE_PATH); if (StringHelper.isNotEmpty(externalResourceBase)) { @@ -34,4 +47,13 @@ public static String getCustomPagesPath() { return externalResourceBase; } + public static String getCustomLocalizationPath() { + String externalResourceBase = System.getProperty(SERVER_BASE_PATH); + if (StringHelper.isNotEmpty(externalResourceBase)) { + externalResourceBase += CUSTOM_LOCALIZATION_PATH; + } + + return externalResourceBase; + } + } diff --git a/oxJsfUtil/src/main/java/org/gluu/jsf2/i18n/ExtendedResourceBundle.java b/oxJsfUtil/src/main/java/org/gluu/jsf2/i18n/ExtendedResourceBundle.java index c9d1b44f7..b271a4383 100644 --- a/oxJsfUtil/src/main/java/org/gluu/jsf2/i18n/ExtendedResourceBundle.java +++ b/oxJsfUtil/src/main/java/org/gluu/jsf2/i18n/ExtendedResourceBundle.java @@ -152,6 +152,12 @@ public ResourceBundle newBundle(String baseName, Locale locale, String format, C InputStream input = null; try { input = loader.getResourceAsStream(resourceName); + + // Fall back to default bundle + if (input == null) { + String defaultResourceName = toResourceName(toBundleName(baseName, Locale.ROOT), "properties"); + input = loader.getResourceAsStream(defaultResourceName); + } InputStreamReader inputReader = new InputStreamReader(input, "UTF-8"); properties.load(inputReader); // Default (internal) bundle. } finally { diff --git a/oxJsfUtil/src/main/java/org/gluu/jsf2/message/FacesMessages.java b/oxJsfUtil/src/main/java/org/gluu/jsf2/message/FacesMessages.java index df6dbc0c5..9d2879daa 100644 --- a/oxJsfUtil/src/main/java/org/gluu/jsf2/message/FacesMessages.java +++ b/oxJsfUtil/src/main/java/org/gluu/jsf2/message/FacesMessages.java @@ -16,7 +16,9 @@ import javax.faces.context.FacesContext; import javax.inject.Inject; +import org.apache.commons.text.StringEscapeUtils; import org.gluu.service.el.ExpressionEvaluator; +import org.gluu.util.StringHelper; /** * @author Yuriy Movchan @@ -48,12 +50,21 @@ public void add(Severity severity, String message) { } public void add(String clientId, Severity severity, String message) { + boolean escape = StringHelper.isNotEmpty(clientId); + add(clientId, severity, message, escape); + } + + public void add(String clientId, Severity severity, String message, boolean escape) { if (facesContext == null) { return; } String evaluatedMessage = evalAsString(message); - FacesMessage facesMessage = new FacesMessage(severity, evaluatedMessage, evaluatedMessage); + String encodedMessage = evaluatedMessage; + if (escape) { + encodedMessage = StringEscapeUtils.escapeHtml4(evaluatedMessage); + } + FacesMessage facesMessage = new FacesMessage(severity, encodedMessage, encodedMessage); facesContext.addMessage(clientId, facesMessage); messages.put(clientId, facesMessage); diff --git a/oxJsfUtil/src/main/java/org/gluu/jsf2/service/FacesService.java b/oxJsfUtil/src/main/java/org/gluu/jsf2/service/FacesService.java index 6f4abf2b9..7ea9bd294 100644 --- a/oxJsfUtil/src/main/java/org/gluu/jsf2/service/FacesService.java +++ b/oxJsfUtil/src/main/java/org/gluu/jsf2/service/FacesService.java @@ -10,8 +10,10 @@ import javax.enterprise.context.RequestScoped; import javax.faces.application.NavigationHandler; import javax.faces.application.ViewHandler; +import javax.faces.component.UIViewRoot; import javax.faces.context.ExternalContext; import javax.faces.context.FacesContext; +import javax.faces.context.PartialViewContext; import javax.inject.Inject; import javax.inject.Named; @@ -115,12 +117,34 @@ public String encodeParameters(String url, Map parameters) { } public void renderView(String viewId) { - final FacesContext fc = FacesContext.getCurrentInstance(); - final ViewHandler viewHandler = fc.getApplication().getViewHandler(); + final FacesContext ctx = FacesContext.getCurrentInstance(); + final ViewHandler viewHandler = ctx.getApplication().getViewHandler(); - fc.setViewRoot(viewHandler.createView(fc, viewId)); - fc.getPartialViewContext().setRenderAll(true); - fc.renderResponse(); + UIViewRoot newRoot = viewHandler.createView(ctx, viewId); + updateRenderTargets(ctx, viewId); + ctx.setViewRoot(newRoot); + clearViewMapIfNecessary(ctx, viewId); + + ctx.renderResponse(); + } + + private void updateRenderTargets(FacesContext ctx, String newId) { + if (ctx.getViewRoot() == null || !ctx.getViewRoot().getViewId().equals(newId)) { + PartialViewContext pctx = ctx.getPartialViewContext(); + if (!pctx.isRenderAll()) { + pctx.setRenderAll(true); + } + } + } + private void clearViewMapIfNecessary(FacesContext facesContext, String newId) { + UIViewRoot root = facesContext.getViewRoot(); + + if (root != null && !root.getViewId().equals(newId)) { + Map viewMap = root.getViewMap(false); + if (viewMap != null) { + viewMap.clear(); + } + } } public void navigateToView(String fromAction, String outcome, Map parameters) { diff --git a/oxService/src/main/java/org/gluu/service/el/ConstantResolver.java b/oxJsfUtil/src/main/java/org/gluu/service/el/ConstantResolver.java similarity index 100% rename from oxService/src/main/java/org/gluu/service/el/ConstantResolver.java rename to oxJsfUtil/src/main/java/org/gluu/service/el/ConstantResolver.java diff --git a/oxService/src/main/java/org/gluu/service/el/ContextProducer.java b/oxJsfUtil/src/main/java/org/gluu/service/el/ContextProducer.java similarity index 100% rename from oxService/src/main/java/org/gluu/service/el/ContextProducer.java rename to oxJsfUtil/src/main/java/org/gluu/service/el/ContextProducer.java diff --git a/oxService/src/main/java/org/gluu/service/el/ExpressionEvaluator.java b/oxJsfUtil/src/main/java/org/gluu/service/el/ExpressionEvaluator.java similarity index 100% rename from oxService/src/main/java/org/gluu/service/el/ExpressionEvaluator.java rename to oxJsfUtil/src/main/java/org/gluu/service/el/ExpressionEvaluator.java diff --git a/oxService/src/main/java/org/gluu/service/el/ExpressionFactoryProducer.java b/oxJsfUtil/src/main/java/org/gluu/service/el/ExpressionFactoryProducer.java similarity index 100% rename from oxService/src/main/java/org/gluu/service/el/ExpressionFactoryProducer.java rename to oxJsfUtil/src/main/java/org/gluu/service/el/ExpressionFactoryProducer.java diff --git a/oxService/src/main/java/org/gluu/service/el/ExtendedELContext.java b/oxJsfUtil/src/main/java/org/gluu/service/el/ExtendedELContext.java similarity index 100% rename from oxService/src/main/java/org/gluu/service/el/ExtendedELContext.java rename to oxJsfUtil/src/main/java/org/gluu/service/el/ExtendedELContext.java diff --git a/oxModel/pom.xml b/oxModel/pom.xml index deaf3eb31..4b48f7ca0 100644 --- a/oxModel/pom.xml +++ b/oxModel/pom.xml @@ -1,4 +1,5 @@ - 4.0.0 @@ -9,19 +10,17 @@ org.gluu oxcore - 4.0.0-SNAPSHOT + 4.5.6-SNAPSHOT org.gluu - oxcore-persistence-annotation - ${project.version} + gluu-orm-annotation org.gluu - oxcore-persistence-model - ${project.version} + gluu-orm-model @@ -29,18 +28,30 @@ validation-api - - com.fasterxml.jackson.core - jackson-annotations - - - com.fasterxml.jackson.core - jackson-core - - - com.fasterxml.jackson.core - jackson-databind - + + com.fasterxml.jackson.core + jackson-annotations + + + com.fasterxml.jackson.core + jackson-core + + + com.fasterxml.jackson.core + jackson-databind + + + javax.annotation + javax.annotation-api + + + jakarta.xml.bind + jakarta.xml.bind-api + + + javax.annotation + javax.annotation-api + \ No newline at end of file diff --git a/oxModel/src/main/java/org/gluu/model/ApplicationType.java b/oxModel/src/main/java/org/gluu/model/ApplicationType.java index e53654ce1..76fd6bdfa 100644 --- a/oxModel/src/main/java/org/gluu/model/ApplicationType.java +++ b/oxModel/src/main/java/org/gluu/model/ApplicationType.java @@ -19,7 +19,8 @@ public enum ApplicationType implements AttributeEnum { OX_AUTH("oxauth", "oxAuth"), - OX_TRUST("oxtrust", "oxTrust"); + OX_TRUST("oxtrust", "oxTrust"), + FIDO2("fido2", "FIDO2"); private String value; private String displayName; diff --git a/oxModel/src/main/java/org/gluu/model/attribute/Attribute.java b/oxModel/src/main/java/org/gluu/model/attribute/Attribute.java index f47be1364..ae6b7eaa6 100644 --- a/oxModel/src/main/java/org/gluu/model/attribute/Attribute.java +++ b/oxModel/src/main/java/org/gluu/model/attribute/Attribute.java @@ -27,7 +27,7 @@ * @author Javier Rojas Blum * @version February 9, 2015 */ -@DataEntry(sortBy = { "displayName" }) +@DataEntry(sortBy = "displayName") @ObjectClass(value = "Attribute") @JsonIgnoreProperties(ignoreUnknown = true) public class Attribute extends Entry implements Serializable { diff --git a/oxModel/src/main/java/org/gluu/model/error/ErrorMessage.java b/oxModel/src/main/java/org/gluu/model/error/ErrorMessage.java new file mode 100644 index 000000000..580f6a354 --- /dev/null +++ b/oxModel/src/main/java/org/gluu/model/error/ErrorMessage.java @@ -0,0 +1,76 @@ +/* + * oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2014, Gluu + */ + +package org.gluu.model.error; + +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + *

+ * Represents an error message in a configuration XML file. + *

+ *

+ * The attribute id is REQUIRED. A single error code. + *

+ *

+ * The element description is OPTIONAL. A human-readable UTF-8 encoded text + * providing additional information, used to assist the client developer in + * understanding the error that occurred. + *

+ *

+ * The element URI is OPTIONAL. A URI identifying a human-readable web page with + * information about the error, used to provide the client developer with + * additional information about the error. + *

+ * + * @author Javier Rojas Date: 09.23.2011 + * + */ +@XmlRootElement(name = "error") +public class ErrorMessage { + + private String id; + private String description; + private String uri; + + public ErrorMessage() { + } + + public ErrorMessage(String id, String description, String uri) { + this.id = id; + this.description = description; + this.uri = uri; + } + + @XmlAttribute(name = "id") + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @XmlElement(name = "error-description") + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @XmlElement(name = "error-uri") + public String getUri() { + return uri; + } + + public void setUri(String uri) { + this.uri = uri; + } +} diff --git a/oxModel/src/main/java/org/gluu/model/metric/MetricType.java b/oxModel/src/main/java/org/gluu/model/metric/MetricType.java index 21336148d..674d14f5a 100644 --- a/oxModel/src/main/java/org/gluu/model/metric/MetricType.java +++ b/oxModel/src/main/java/org/gluu/model/metric/MetricType.java @@ -30,7 +30,18 @@ public enum MetricType implements AttributeEnum { OXAUTH_USER_AUTHENTICATION_RATE("user_authentication_rate", "User authentication rate", TimerMetricData.class, TimerMetricEntry.class), DYNAMIC_CLIENT_REGISTRATION_RATE("dynamic_client_registration_rate", - "Dynamic client registration rate", TimerMetricData.class, TimerMetricEntry.class); + "Dynamic client registration rate", TimerMetricData.class, TimerMetricEntry.class), + + OXAUTH_TOKEN_AUTHORIZATION_CODE_COUNT("tkn_authorization_code_count", + "Count successfull issued oxAuth authorization code tokens", CounterMetricData.class, CounterMetricEntry.class), + OXAUTH_TOKEN_ACCESS_TOKEN_COUNT("tkn_access_token_count", + "Count successfull issued oxAuth access tokens", CounterMetricData.class, CounterMetricEntry.class), + OXAUTH_TOKEN_ID_TOKEN_COUNT("tkn_id_token_count", + "Count successfull issued oxAuth id tokens", CounterMetricData.class, CounterMetricEntry.class), + OXAUTH_TOKEN_REFRESH_TOKEN_COUNT("tkn_refresh_token_count", + "Count successfull issued oxAuth refresh tokens", CounterMetricData.class, CounterMetricEntry.class), + OXAUTH_TOKEN_LONG_LIVED_ACCESS_TOKEN_COUNT("tkn_long_lived_access_token_count", + "Count successfull issued oxAuth long lived access tokens", CounterMetricData.class, CounterMetricEntry.class); private String value; private String displayName; diff --git a/oxModel/src/main/java/org/gluu/model/metric/ldap/MetricEntry.java b/oxModel/src/main/java/org/gluu/model/metric/ldap/MetricEntry.java index 822f1826a..3dd0e3414 100644 --- a/oxModel/src/main/java/org/gluu/model/metric/ldap/MetricEntry.java +++ b/oxModel/src/main/java/org/gluu/model/metric/ldap/MetricEntry.java @@ -10,6 +10,7 @@ import org.gluu.persist.annotation.AttributeName; import org.gluu.persist.annotation.DN; import org.gluu.persist.annotation.DataEntry; +import org.gluu.persist.annotation.Expiration; import org.gluu.persist.annotation.ObjectClass; import java.util.Date; @@ -19,7 +20,7 @@ * * @author Yuriy Movchan Date: 07/27/2015 */ -@DataEntry(sortBy = "startDate") +@DataEntry(sortBy = "startDate", sortByName = "oxStartDate") @ObjectClass(value = "oxMetric") public class MetricEntry { @@ -44,8 +45,15 @@ public class MetricEntry { @AttributeName(name = "creationDate") private Date creationDate; - @AttributeName(name = "oxAuthExpiration") + @AttributeName(name = "oxHost") + private String nodeIndetifier; + + @AttributeName(name = "exp") private Date expirationDate; + + @Expiration + private Integer ttl; + @AttributeName(name = "del") private boolean deletable = true; @@ -114,7 +122,15 @@ public void setCreationDate(Date creationDate) { this.creationDate = creationDate; } - public Date getExpirationDate() { + public String getNodeIndetifier() { + return nodeIndetifier; + } + + public void setNodeIndetifier(String nodeIndetifier) { + this.nodeIndetifier = nodeIndetifier; + } + + public Date getExpirationDate() { return expirationDate; } @@ -122,7 +138,15 @@ public void setExpirationDate(Date expirationDate) { this.expirationDate = expirationDate; } - public boolean isDeletable() { + public Integer getTtl() { + return ttl; + } + + public void setTtl(Integer ttl) { + this.ttl = ttl; + } + + public boolean isDeletable() { return deletable; } @@ -130,19 +154,10 @@ public void setDeletable(boolean deletable) { this.deletable = deletable; } - @Override - public String toString() { - return "MetricEntry{" + - "dn='" + dn + '\'' + - ", id='" + id + '\'' + - ", startDate=" + startDate + - ", endDate=" + endDate + - ", applicationType=" + applicationType + - ", metricType=" + metricType + - ", creationDate=" + creationDate + - ", expirationDate=" + expirationDate + - ", deletable=" + deletable + - '}'; - } + public String toString() { + return "MetricEntry [dn=" + dn + ", id=" + id + ", startDate=" + startDate + ", endDate=" + endDate + ", applicationType=" + + applicationType + ", metricType=" + metricType + ", creationDate=" + creationDate + ", nodeIndetifier=" + nodeIndetifier + + ", expirationDate=" + expirationDate + ", deletable=" + deletable + "]"; + } } diff --git a/oxModel/src/main/java/org/gluu/model/types/LoggingLayoutType.java b/oxModel/src/main/java/org/gluu/model/types/LoggingLayoutType.java new file mode 100644 index 000000000..efb1c3481 --- /dev/null +++ b/oxModel/src/main/java/org/gluu/model/types/LoggingLayoutType.java @@ -0,0 +1,48 @@ +/* + * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2014, Gluu + */ + +package org.gluu.model.types; + +import java.util.HashMap; +import java.util.Map; + +/** + * Different layouts available to be used as logs. + * + */ +public enum LoggingLayoutType { + + TEXT("TEXT"), + JSON("JSON"); + + private String value; + + private static Map MAP_BY_VALUES = new HashMap(); + + static { + for (LoggingLayoutType enumType : values()) { + MAP_BY_VALUES.put(enumType.getValue(), enumType); + } + } + + LoggingLayoutType(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + public static LoggingLayoutType getByValue(String value) { + return MAP_BY_VALUES.get(value); + } + + @Override + public String toString() { + return value; + } + +} diff --git a/oxRadius/pom.xml b/oxRadius/pom.xml index f82285785..66c3fd2ed 100644 --- a/oxRadius/pom.xml +++ b/oxRadius/pom.xml @@ -8,19 +8,17 @@ org.gluu oxcore - 4.0.0-SNAPSHOT + 4.5.6-SNAPSHOT org.gluu - oxcore-persistence-ldap - ${project.version} + gluu-orm-ldap org.gluu - oxcore-persistence-annotation - ${project.version} + gluu-orm-annotation diff --git a/oxSaml/pom.xml b/oxSaml/pom.xml index 927a21449..a5c0e31ea 100644 --- a/oxSaml/pom.xml +++ b/oxSaml/pom.xml @@ -9,23 +9,79 @@ org.gluu oxcore - 4.0.0-SNAPSHOT + 4.5.6-SNAPSHOT + + + + src/main/resources + true + + **/*.xml + **/services/* + **/*.properties + + + + + + src/test/resources + true + + **/*.xml + **/services/* + **/*.properties + + + + + + + + javax.enterprise + cdi-api + provided + + + org.gluu oxcore-util - ${project.version} - org.apache.ws.security - wss4j + org.gluu + oxcore-document-store + commons-beanutils commons-beanutils - 1.9.3 + + + org.apache.ws.security + wss4j + + + org.opensaml + opensaml + + + ca.juliusdavies + not-yet-commons-ssl + + + + + jakarta.xml.bind + jakarta.xml.bind-api + + + + + org.apache.santuario + xmlsec -
\ No newline at end of file + diff --git a/oxSaml/src/main/java/org/gluu/saml/Response.java b/oxSaml/src/main/java/org/gluu/saml/Response.java index 57800a94c..348316a5a 100644 --- a/oxSaml/src/main/java/org/gluu/saml/Response.java +++ b/oxSaml/src/main/java/org/gluu/saml/Response.java @@ -37,7 +37,6 @@ import javax.xml.xpath.XPathFactory; import org.apache.commons.codec.binary.Base64; -import org.gluu.xml.SimpleNamespaceContext; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -86,15 +85,15 @@ public void loadXml(String xml) throws ParserConfigurationException, SAXExceptio fty.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); DocumentBuilder builder = fty.newDocumentBuilder(); - ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes()); + ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes("UTF-8")); xmlDoc = builder.parse(bais); } public void loadXmlFromBase64(String response) throws ParserConfigurationException, SAXException, IOException { Base64 base64 = new Base64(); byte[] decodedResponse = base64.decode(response); - String decodedS = new String(decodedResponse); - loadXml(decodedS); + String decoded = new String(decodedResponse, "UTF-8"); + loadXml(decoded); } public boolean isValid() throws Exception { @@ -116,6 +115,30 @@ public boolean isValid() throws Exception { return xmlSignature.validate(ctx); } + + public boolean isValidNew() throws Exception { + NodeList nodes = xmlDoc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature"); + + if (nodes == null || nodes.getLength() == 0) { + throw new Exception("Can't find signature in document."); + } + + if (setIdAttributeExists()) { + tagIdAttributes(xmlDoc); + } + + X509Certificate cert = samlSettings.getCertificate(); + + // It's do initialization only on first call + org.apache.xml.security.Init.init(); + + Element sigElement = (Element) nodes.item(0); + org.apache.xml.security.signature.XMLSignature signature = new org.apache.xml.security.signature.XMLSignature( + sigElement, null); + + return signature.checkSignatureValue(cert); + } + public boolean isAuthnFailed() throws Exception { XPath xPath = XPathFactory.newInstance().newXPath(); diff --git a/oxSaml/src/main/java/org/gluu/saml/SimpleNamespaceContext.java b/oxSaml/src/main/java/org/gluu/saml/SimpleNamespaceContext.java new file mode 100644 index 000000000..8b8750f61 --- /dev/null +++ b/oxSaml/src/main/java/org/gluu/saml/SimpleNamespaceContext.java @@ -0,0 +1,44 @@ +/* + * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2014, Gluu + */ + +package org.gluu.saml; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import javax.xml.namespace.NamespaceContext; + +/** + * Allow to work with XML name contexts + * + * @author Yuriy Movchan Date: 04/24/2014 + */ +public class SimpleNamespaceContext implements NamespaceContext { + private final Map prefMap = new HashMap(); + + @Override + public String getNamespaceURI(String prefix) { + return prefMap.get(prefix); + } + + @Override + public String getPrefix(String namespaceURI) { + return prefMap.get(namespaceURI); + } + + @SuppressWarnings("rawtypes") + @Override + public Iterator getPrefixes(String namespaceURI) { + // TODO Auto-generated method stub + return null; + } + + public SimpleNamespaceContext(final Map prefMap) { + prefMap.putAll(prefMap); + } + +} diff --git a/oxSaml/src/main/java/org/gluu/saml/metadata/SAMLMetadataParser.java b/oxSaml/src/main/java/org/gluu/saml/metadata/SAMLMetadataParser.java index 950fdd1d2..9ff3aa1a9 100644 --- a/oxSaml/src/main/java/org/gluu/saml/metadata/SAMLMetadataParser.java +++ b/oxSaml/src/main/java/org/gluu/saml/metadata/SAMLMetadataParser.java @@ -5,23 +5,34 @@ */ package org.gluu.saml.metadata; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.io.StringBufferInputStream; import java.net.URL; import java.util.List; +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.gluu.util.io.HTTPFileDownloader; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.gluu.service.document.store.service.DocumentStoreService; +import org.slf4j.Logger; import org.xml.sax.SAXException; /** @@ -29,34 +40,55 @@ * * @author Dmitry Ognyannikov */ -public final class SAMLMetadataParser { - private static final Log LOG = LogFactory.getLog(SAMLMetadataParser.class); - private SAMLMetadataParser() { } +@ApplicationScoped +public class SAMLMetadataParser { - public static List getEntityIdFromMetadataFile(File metadataFile) { - if (!metadataFile.isFile()) { + @Inject + private Logger log; + + @Inject + private DocumentStoreService documentStoreService; + + public List getEntityIdFromMetadataFile(String metadataFile) { + if (!documentStoreService.hasDocument(metadataFile)) { return null; } + EntityIDHandler handler = parseMetadata(metadataFile); if(handler!=null){ List entityIds = handler.getEntityIDs(); if (entityIds == null || entityIds.isEmpty()) { - LOG.error("Failed to find entityId in metadata file: " + metadataFile.getAbsolutePath()); + log.error("Failed to find entityId in metadata file: " + metadataFile); } return entityIds; }else{ return null; } } + + public List getEntityIdFromMetadataFile(File metadataFile) { + if (!metadataFile.isFile()) { + return null; + } + EntityIDHandler handler = parseMetadata(metadataFile); + + List entityIds = handler.getEntityIDs(); + + if (entityIds == null || entityIds.isEmpty()) { + log.error("Failed to find entityId in metadata file: " + metadataFile.getAbsolutePath()); + } - public static List getSpEntityIdFromMetadataFile(File metadataFile) { + return entityIds; + } + + public List getSpEntityIdFromMetadataFile(String metadataFile) { EntityIDHandler handler = parseMetadata(metadataFile); if(handler!=null){ List entityIds = handler.getSpEntityIDs(); if (entityIds == null || entityIds.isEmpty()) { - LOG.error("Failed to find entityId in metadata file: " + metadataFile.getAbsolutePath()); + log.error("Failed to find entityId in metadata file: " + metadataFile); } return entityIds; @@ -66,25 +98,45 @@ public static List getSpEntityIdFromMetadataFile(File metadataFile) { } - public static EntityIDHandler parseMetadata(File metadataFile) { + public EntityIDHandler parseMetadata(String metadataFile) { + if (!documentStoreService.hasDocument(metadataFile)) { + log.error("Failed to get entityId from metadata file: " + metadataFile); + return null; + } + + InputStream is = null; + try { + is = documentStoreService.readDocumentAsStream(metadataFile); + + return parseMetadata(is); + } catch (Exception ex) { + log.error("Failed to read SAML metadata file: " + metadataFile, ex); + return null; + } finally { + IOUtils.closeQuietly(is); + } + } + + public EntityIDHandler parseMetadata(File metadataFile) { if (!metadataFile.exists()) { - LOG.error("Failed to get entityId from metadata file: " + metadataFile.getAbsolutePath()); + log.error("Failed to get entityId from metadata file: " + metadataFile.getAbsolutePath()); return null; } + InputStream is = null; try { is = FileUtils.openInputStream(metadataFile); - + return parseMetadata(is); } catch (IOException ex) { - LOG.error("Failed to read SAML metadata file: " + metadataFile.getAbsolutePath(), ex); + log.error("Failed to read SAML metadata file: " + metadataFile.getAbsolutePath(), ex); return null; } finally { IOUtils.closeQuietly(is); } } - public static EntityIDHandler parseMetadata(InputStream is) { + public EntityIDHandler parseMetadata(InputStream is) { InputStreamReader isr = null; EntityIDHandler handler = null; try { @@ -93,11 +145,11 @@ public static EntityIDHandler parseMetadata(InputStream is) { handler = new EntityIDHandler(); saxParser.parse(is, handler); } catch (IOException ex) { - LOG.error("Failed to read SAML metadata", ex); + log.error("Failed to read SAML metadata", ex); } catch (ParserConfigurationException e) { - LOG.error("Failed to confugure SAX parser", e); + log.error("Failed to confugure SAX parser", e); } catch (SAXException e) { - LOG.error("Failed to parse SAML metadata", e); + log.error("Failed to parse SAML metadata", e); } finally { IOUtils.closeQuietly(isr); IOUtils.closeQuietly(is); @@ -107,16 +159,51 @@ public static EntityIDHandler parseMetadata(InputStream is) { return handler; } - public static EntityIDHandler parseMetadata(URL metadataURL) { - String metadataFileContent = HTTPFileDownloader.getResource(metadataURL.toExternalForm(), "application/xml, text/xml", null, null); - return parseMetadata(metadataFileContent); + public EntityIDHandler parseMetadata(URL metadataURL) throws ClientProtocolException, IOException { + byte[] metadataFileContent = downloadMetadata(metadataURL.toExternalForm()); + + InputStream is = new ByteArrayInputStream(metadataFileContent); + + return parseMetadata(is); } - public static EntityIDHandler parseMetadata(String metadata) { - if (metadata == null) { + public byte[] downloadMetadata(String metadataURL) throws IOException, ClientProtocolException { + HttpGet httpGet = new HttpGet(metadataURL); + httpGet.setHeader("Accept", "application/xml, text/xml"); + + byte[] metadataFileContent = null; + try ( CloseableHttpClient httpClient = HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build()) + .build() ) { + HttpResponse httpResponse = httpClient.execute(httpGet); + metadataFileContent = getResponseContent(httpResponse); + } + + if (metadataFileContent == null) { return null; } - InputStream is = new StringBufferInputStream(metadata); - return parseMetadata(is); - } + + return metadataFileContent; + } + + public byte[] getResponseContent(HttpResponse httpResponse) throws IOException { + if ((httpResponse == null) || (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK)) { + return null; + } + + HttpEntity entity = httpResponse.getEntity(); + byte[] responseBytes = new byte[0]; + if (entity != null) { + responseBytes = EntityUtils.toByteArray(entity); + } + + // Consume response content + if (entity != null) { + EntityUtils.consume(entity); + } + + return responseBytes; + } + } + diff --git a/oxSaml/src/main/resources/META-INF/beans.xml b/oxSaml/src/main/resources/META-INF/beans.xml new file mode 100644 index 000000000..2f4f7e279 --- /dev/null +++ b/oxSaml/src/main/resources/META-INF/beans.xml @@ -0,0 +1,7 @@ + + + diff --git a/oxService/.gitignore b/oxService/.gitignore new file mode 100644 index 000000000..466ffd096 --- /dev/null +++ b/oxService/.gitignore @@ -0,0 +1 @@ +/test-output/ diff --git a/oxService/pom.xml b/oxService/pom.xml index dee44b8be..cfb66e9e2 100644 --- a/oxService/pom.xml +++ b/oxService/pom.xml @@ -10,7 +10,7 @@ org.gluu oxcore - 4.0.0-SNAPSHOT + 4.5.6-SNAPSHOT @@ -25,17 +25,17 @@ - - - src/test/resources - true - - **/*.xml - **/services/* - **/*.properties - - - + + + src/test/resources + true + + **/*.xml + **/services/* + **/*.properties + + + @@ -43,46 +43,60 @@ ${project.groupId} oxcore-model - ${project.version} ${project.groupId} - oxcore-persistence-ldap - ${project.version} + gluu-orm-ldap + + + ${project.groupId} + gluu-orm-couchbase + + + ${project.groupId} + gluu-orm-spanner + + + ${project.groupId} + gluu-orm-sql + + + ${project.groupId} + gluu-orm-hybrid - - ${project.groupId} - oxcore-persistence-couchbase - ${project.version} - ${project.groupId} oxcore-util - ${project.version} + + + ${project.groupId} + oxcore-cache + + + ${project.groupId} + oxcore-script + + + ${project.groupId} + oxcore-cdi - + javax.enterprise cdi-api provided - - com.sun.faces - jsf-api - provided - javax.servlet javax.servlet-api provided - org.jboss.weld - weld-core-impl + org.jboss.spec.javax.annotation + jboss-annotations-api_1.2_spec provided - javax.inject javax.inject @@ -92,30 +106,18 @@ validation-api - - org.jboss.spec.javax.ejb - jboss-ejb-api_3.2_spec - provided - - + com.sun.faces - jsf-impl + jsf-api provided - org.glassfish.web el-impl provided - - - org.python - jython-standalone - - net.spy @@ -137,16 +139,9 @@ - - com.google.guava - guava - ${guava.version} - - - - org.quartz-scheduler - quartz + com.google.guava + guava @@ -157,8 +152,27 @@ - javax.mail - mail + com.sun.mail + jakarta.mail + + + com.fasterxml + aalto-xml + 1.2.1 + + + + + org.bouncycastle + bcprov-jdk18on + + + org.bouncycastle + bcpkix-jdk18on + + + org.bouncycastle + bcmail-jdk18on diff --git a/oxService/src/main/java/org/gluu/config/oxtrust/AppConfiguration.java b/oxService/src/main/java/org/gluu/config/oxtrust/AppConfiguration.java index d2949dd87..92352ceb0 100644 --- a/oxService/src/main/java/org/gluu/config/oxtrust/AppConfiguration.java +++ b/oxService/src/main/java/org/gluu/config/oxtrust/AppConfiguration.java @@ -8,9 +8,10 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; - import javax.enterprise.inject.Vetoed; +import org.gluu.model.LocaleSupported; import java.io.Serializable; +import java.util.Arrays; import java.util.List; @@ -38,23 +39,18 @@ public class AppConfiguration implements Configuration, Serializable { private String personCustomObjectClass; private String[] personObjectClassDisplayNames; + private List adminUiLocaleSupported; + private String[] contactObjectClassTypes; private String[] contactObjectClassDisplayNames; - private String photoRepositoryRootDir; - private int photoRepositoryThumbWidth; - private int photoRepositoryThumbHeight; - private int photoRepositoryCountLeveles; - private int photoRepositoryCountFoldersPerLevel; - private String ldifStore; + + private int keepLdifStoreHistoryDays; private boolean updateStatus; - private String svnConfigurationStoreRoot; - private String svnConfigurationStorePassword; - private String keystorePath; private String keystorePassword; @@ -64,8 +60,6 @@ public class AppConfiguration implements Configuration, Serializable { private String spMetadataPath; - private String logoLocation; - private String idpSecurityKey; private String idpSecurityKeyPassword; private String idpSecurityCert; @@ -84,15 +78,11 @@ public class AppConfiguration implements Configuration, Serializable { private String shibboleth3FederationRootDir; - private String caCertsLocation; - private String caCertsPassphrase; private String tempCertDir; private String certDir; private String servicesRestartTrigger; - private boolean persistSVN; - private String oxAuthSectorIdentifierUrl; private String oxAuthClientId; @@ -127,7 +117,7 @@ public class AppConfiguration implements Configuration, Serializable { private String apiUmaClientId; private String apiUmaClientKeyId; private String apiUmaResourceId; - private String[] apiUmaScopes; + private String apiUmaScope; private String apiUmaClientKeyStoreFile; private String apiUmaClientKeyStorePassword; @@ -138,8 +128,8 @@ public class AppConfiguration implements Configuration, Serializable { private String recaptchaSecretKey; private boolean authenticationRecaptchaEnabled; - private boolean scimTestMode; private boolean oxTrustApiTestMode; + private boolean enableUpdateNotification; private boolean rptConnectionPoolUseConnectionPooling; private int rptConnectionPoolMaxTotal; @@ -151,8 +141,10 @@ public class AppConfiguration implements Configuration, Serializable { private List clientWhiteList; private List clientBlackList; + private List supportedUserStatus= Arrays.asList("active","inactive"); private String loggingLevel; + private String loggingLayout; private String shibbolethVersion; private String shibboleth3IdpRootDir; @@ -163,7 +155,7 @@ public class AppConfiguration implements Configuration, Serializable { private int metricReporterInterval; private int metricReporterKeepDataDays; - private Boolean metricReporterEnabled = true; + private Boolean metricReporterEnabled; private Boolean disableJdkLogger = true; @JsonProperty("ScimProperties") @@ -173,6 +165,12 @@ public class AppConfiguration implements Configuration, Serializable { private int cleanServiceInterval; private Boolean enforceEmailUniqueness = true; + private Boolean useLocalCache = false; + + private boolean passIdTokenHintToLogoutRedirectUri = false; + private OxTrustApiMode oxTrustProtectionMode; + private String auditConfigLogsLocation; + public ScimProperties getScimProperties() { return scimProperties; } @@ -261,45 +259,7 @@ public void setContactObjectClassDisplayNames(String[] contactObjectClassDisplay this.contactObjectClassDisplayNames = contactObjectClassDisplayNames; } - public String getPhotoRepositoryRootDir() { - return photoRepositoryRootDir; - } - - public void setPhotoRepositoryRootDir(String photoRepositoryRootDir) { - this.photoRepositoryRootDir = photoRepositoryRootDir; - } - - public int getPhotoRepositoryThumbWidth() { - return photoRepositoryThumbWidth; - } - public void setPhotoRepositoryThumbWidth(int photoRepositoryThumbWidth) { - this.photoRepositoryThumbWidth = photoRepositoryThumbWidth; - } - - public int getPhotoRepositoryThumbHeight() { - return photoRepositoryThumbHeight; - } - - public void setPhotoRepositoryThumbHeight(int photoRepositoryThumbHeight) { - this.photoRepositoryThumbHeight = photoRepositoryThumbHeight; - } - - public int getPhotoRepositoryCountLeveles() { - return photoRepositoryCountLeveles; - } - - public void setPhotoRepositoryCountLeveles(int photoRepositoryCountLeveles) { - this.photoRepositoryCountLeveles = photoRepositoryCountLeveles; - } - - public int getPhotoRepositoryCountFoldersPerLevel() { - return photoRepositoryCountFoldersPerLevel; - } - - public void setPhotoRepositoryCountFoldersPerLevel(int photoRepositoryCountFoldersPerLevel) { - this.photoRepositoryCountFoldersPerLevel = photoRepositoryCountFoldersPerLevel; - } public String getLdifStore() { return ldifStore; @@ -317,21 +277,6 @@ public void setUpdateStatus(boolean updateStatus) { this.updateStatus = updateStatus; } - public String getSvnConfigurationStoreRoot() { - return svnConfigurationStoreRoot; - } - - public void setSvnConfigurationStoreRoot(String svnConfigurationStoreRoot) { - this.svnConfigurationStoreRoot = svnConfigurationStoreRoot; - } - - public String getSvnConfigurationStorePassword() { - return svnConfigurationStorePassword; - } - - public void setSvnConfigurationStorePassword(String svnConfigurationStorePassword) { - this.svnConfigurationStorePassword = svnConfigurationStorePassword; - } public String getKeystorePath() { return keystorePath; @@ -372,15 +317,6 @@ public String getSpMetadataPath() { public void setSpMetadataPath(String spMetadataPath) { this.spMetadataPath = spMetadataPath; } - - public String getLogoLocation() { - return logoLocation; - } - - public void setLogoLocation(String logoLocation) { - this.logoLocation = logoLocation; - } - public String getIdpSecurityKey() { return idpSecurityKey; } @@ -477,22 +413,6 @@ public void setShibboleth3FederationRootDir(String shibboleth3FederationRootDir) this.shibboleth3FederationRootDir = shibboleth3FederationRootDir; } - public String getCaCertsLocation() { - return caCertsLocation; - } - - public void setCaCertsLocation(String caCertsLocation) { - this.caCertsLocation = caCertsLocation; - } - - public String getCaCertsPassphrase() { - return caCertsPassphrase; - } - - public void setCaCertsPassphrase(String caCertsPassphrase) { - this.caCertsPassphrase = caCertsPassphrase; - } - public String getTempCertDir() { return tempCertDir; } @@ -517,14 +437,6 @@ public void setServicesRestartTrigger(String servicesRestartTrigger) { this.servicesRestartTrigger = servicesRestartTrigger; } - public boolean isPersistSVN() { - return persistSVN; - } - - public void setPersistSVN(boolean persistSVN) { - this.persistSVN = persistSVN; - } - public String getOxAuthSectorIdentifierUrl() { return oxAuthSectorIdentifierUrl; } @@ -733,14 +645,6 @@ public void setRecaptchaSecretKey(String recaptchaSecretKey) { this.recaptchaSecretKey = recaptchaSecretKey; } - public boolean isScimTestMode() { - return scimTestMode; - } - - public void setScimTestMode(boolean scimTestMode) { - this.scimTestMode = scimTestMode; - } - public boolean isOxTrustApiTestMode() { return oxTrustApiTestMode; } @@ -861,6 +765,14 @@ public void setLoggingLevel(String loggingLevel) { this.loggingLevel = loggingLevel; } + public String getLoggingLayout() { + return loggingLayout; + } + + public void setLoggingLayout(String loggingLayout) { + this.loggingLayout = loggingLayout; + } + public int getMetricReporterInterval() { return metricReporterInterval; } @@ -869,6 +781,14 @@ public void setMetricReporterInterval(int metricReporterInterval) { this.metricReporterInterval = metricReporterInterval; } + public List getSupportedUserStatus() { + return supportedUserStatus; + } + + public void setSupportedUserStatus(List supportedUserStatus) { + this.supportedUserStatus = supportedUserStatus; + } + /** * @return the apiUmaClientId */ @@ -914,12 +834,12 @@ public void setApiUmaResourceId(String apiUmaResourceId) { this.apiUmaResourceId = apiUmaResourceId; } - public String[] getApiUmaScopes() { - return apiUmaScopes; + public String getApiUmaScope() { + return apiUmaScope; } - public void setApiUmaScopes(String[] apiUmaScopes) { - this.apiUmaScopes = apiUmaScopes; + public void setApiUmaScope(String apiUmaScope) { + this.apiUmaScope = apiUmaScope; } /** @@ -1007,4 +927,60 @@ public Boolean getEnforceEmailUniqueness() { public void setEnforceEmailUniqueness(Boolean enforceEmailUniqueness) { this.enforceEmailUniqueness = enforceEmailUniqueness; } + + public Boolean getUseLocalCache() { + return useLocalCache; + } + + public void setUseLocalCache(Boolean useLocalCache) { + this.useLocalCache = useLocalCache; + } + + public boolean isEnableUpdateNotification() { + return enableUpdateNotification; + } + + public void setEnableUpdateNotification(boolean enableUpdateNotification) { + this.enableUpdateNotification = enableUpdateNotification; + } + + public boolean isPassIdTokenHintToLogoutRedirectUri() { + return passIdTokenHintToLogoutRedirectUri; + } + + public void setPassIdTokenHintToLogoutRedirectUri(boolean passIdTokenHintToLogoutRedirectUri) { + this.passIdTokenHintToLogoutRedirectUri = passIdTokenHintToLogoutRedirectUri; + } + + public List getAdminUiLocaleSupported() { + return adminUiLocaleSupported; + } + + public void setAdminUiLocaleSupported(List adminUiLocaleSupported) { + this.adminUiLocaleSupported = adminUiLocaleSupported; + } + + public int getKeepLdifStoreHistoryDays() { + return keepLdifStoreHistoryDays; + } + + public void setKeepLdifStoreHistoryDays(int keepLdifStoreHistoryDays) { + this.keepLdifStoreHistoryDays = keepLdifStoreHistoryDays; + } + + public OxTrustApiMode getOxTrustProtectionMode() { + return oxTrustProtectionMode; + } + + public void setOxTrustProtectionMode(OxTrustApiMode oxTrustProtectionMode) { + this.oxTrustProtectionMode = oxTrustProtectionMode; + } + + public String getAuditConfigLogsLocation() { + return auditConfigLogsLocation; + } + + public void setAuditConfigLogsLocation(String auditConfigLogsLocation) { + this.auditConfigLogsLocation = auditConfigLogsLocation; + } } diff --git a/oxService/src/main/java/org/gluu/config/oxtrust/DbApplicationConfiguration.java b/oxService/src/main/java/org/gluu/config/oxtrust/DbApplicationConfiguration.java new file mode 100644 index 000000000..4173d1026 --- /dev/null +++ b/oxService/src/main/java/org/gluu/config/oxtrust/DbApplicationConfiguration.java @@ -0,0 +1,63 @@ +/* + * oxTrust is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Gluu + */ + +package org.gluu.config.oxtrust; + +import org.gluu.persist.annotation.AttributeName; +import org.gluu.persist.annotation.DN; +import org.gluu.persist.annotation.DataEntry; +import org.gluu.persist.annotation.JsonObject; +import org.gluu.persist.annotation.ObjectClass; + +/** + * @author Yuriy MOvchan + * @version May 12, 2020 + */ +@DataEntry +@ObjectClass(value = "gluuApplicationConfiguration") +public class DbApplicationConfiguration { + @DN + private String dn; + + @JsonObject + @AttributeName(name = "gluuConfDynamic") + private String dynamicConf; + + @AttributeName(name = "oxRevision") + private long revision; + + public DbApplicationConfiguration() { + } + + public String getDn() { + return dn; + } + + public void setDn(String p_dn) { + dn = p_dn; + } + + public String getDynamicConf() { + return dynamicConf; + } + + public void setDynamicConf(String dynamicConf) { + this.dynamicConf = dynamicConf; + } + + public long getRevision() { + return revision; + } + + public void setRevision(long revision) { + this.revision = revision; + } + + @Override + public String toString() { + return "DbApplicationConfiguration [dn=" + dn + ", dynamicConf=" + dynamicConf + ", revision=" + revision + "]"; + } +} diff --git a/oxService/src/main/java/org/gluu/config/oxtrust/OxTrustApiMode.java b/oxService/src/main/java/org/gluu/config/oxtrust/OxTrustApiMode.java new file mode 100644 index 000000000..81de7310a --- /dev/null +++ b/oxService/src/main/java/org/gluu/config/oxtrust/OxTrustApiMode.java @@ -0,0 +1,3 @@ +package org.gluu.config.oxtrust; + +public enum OxTrustApiMode { OAUTH, TEST, UMA }; diff --git a/oxService/src/main/java/org/gluu/config/oxtrust/ScimMode.java b/oxService/src/main/java/org/gluu/config/oxtrust/ScimMode.java new file mode 100644 index 000000000..45bf82f10 --- /dev/null +++ b/oxService/src/main/java/org/gluu/config/oxtrust/ScimMode.java @@ -0,0 +1,3 @@ +package org.gluu.config.oxtrust; + +public enum ScimMode { OAUTH, TEST, UMA, BYPASS }; diff --git a/oxService/src/main/java/org/gluu/config/oxtrust/ScimProperties.java b/oxService/src/main/java/org/gluu/config/oxtrust/ScimProperties.java index 5f8220731..5f8957d19 100644 --- a/oxService/src/main/java/org/gluu/config/oxtrust/ScimProperties.java +++ b/oxService/src/main/java/org/gluu/config/oxtrust/ScimProperties.java @@ -4,7 +4,6 @@ import java.io.Serializable; - @JsonIgnoreProperties(ignoreUnknown = true) public class ScimProperties implements Serializable { @@ -14,13 +13,51 @@ public class ScimProperties implements Serializable { private static final long serialVersionUID = -5154249316054593386L; private int maxCount; + private int bulkMaxOperations; + private long bulkMaxPayloadSize; + + private ScimMode protectionMode; + + private String userExtensionSchemaURI; public int getMaxCount() { - return this.maxCount; + return maxCount; } public void setMaxCount(int maxCount) { this.maxCount = maxCount; } + + public int getBulkMaxOperations() { + return bulkMaxOperations; + } + + public void setBulkMaxOperations(int bulkMaxOperations) { + this.bulkMaxOperations = bulkMaxOperations; + } + + public long getBulkMaxPayloadSize() { + return bulkMaxPayloadSize; + } + + public void setBulkMaxPayloadSize(long bulkMaxPayloadSize) { + this.bulkMaxPayloadSize = bulkMaxPayloadSize; + } + + public ScimMode getProtectionMode() { + return protectionMode; + } + + public void setProtectionMode(ScimMode mode) { + protectionMode = mode; + } + + public String getUserExtensionSchemaURI() { + return userExtensionSchemaURI; + } + + public void setUserExtensionSchemaURI(String userExtensionSchemaURI) { + this.userExtensionSchemaURI = userExtensionSchemaURI; + } } diff --git a/oxService/src/main/java/org/gluu/model/DisplayNameEntry.java b/oxService/src/main/java/org/gluu/model/DisplayNameEntry.java index 624f7c73a..efeb8e3dd 100644 --- a/oxService/src/main/java/org/gluu/model/DisplayNameEntry.java +++ b/oxService/src/main/java/org/gluu/model/DisplayNameEntry.java @@ -10,6 +10,7 @@ import org.gluu.persist.model.base.Entry; import org.gluu.persist.annotation.AttributeName; +import org.gluu.persist.annotation.CustomObjectClass; import org.gluu.persist.annotation.DataEntry; /** @@ -17,7 +18,7 @@ * * @author Yuriy Movchan Date: 08/11/2010 */ -@DataEntry(sortBy = { "displayName" }) +@DataEntry(sortBy = "displayName") public class DisplayNameEntry extends Entry implements Serializable { private static final long serialVersionUID = 2536007777903091939L; @@ -31,15 +32,15 @@ public DisplayNameEntry(String dn, String inum, String displayName) { this.displayName = displayName; } + @CustomObjectClass + private String[] customObjectClasses; + @AttributeName(ignoreDuringUpdate = true) private String inum; @AttributeName private String displayName; - @AttributeName - private String uid; - public String getInum() { return inum; } @@ -61,19 +62,12 @@ public String toString() { return String.format("DisplayNameEntry [displayName=%s, inum=%s, toString()=%s]", displayName, inum, super.toString()); } - /** - * @param uid - * the uid to set - */ - public void setUid(String uid) { - this.uid = uid; + public String[] getCustomObjectClasses() { + return customObjectClasses; } - /** - * @return the uid - */ - public String getUid() { - return uid; + public void setCustomObjectClasses(String[] customObjectClasses) { + this.customObjectClasses = customObjectClasses; } } diff --git a/oxService/src/main/java/org/gluu/model/GluuAttribute.java b/oxService/src/main/java/org/gluu/model/GluuAttribute.java index fb2d1cdf9..eb1acf57c 100644 --- a/oxService/src/main/java/org/gluu/model/GluuAttribute.java +++ b/oxService/src/main/java/org/gluu/model/GluuAttribute.java @@ -28,7 +28,7 @@ * @author Javier Rojas Blum * @version May 2, 2019 */ -@DataEntry(sortBy = { "displayName" }) +@DataEntry(sortBy = "displayName") @ObjectClass(value = "gluuAttribute") public class GluuAttribute extends Entry implements Serializable { @@ -39,20 +39,14 @@ public class GluuAttribute extends Entry implements Serializable { @AttributeName(ignoreDuringUpdate = true) private String inum; - @AttributeName - private String lifetime; - @AttributeName(name = "oxSourceAttribute") private String sourceAttribute; - @AttributeName - private String salt; - @AttributeName(name = "oxNameIdType") private String nameIdType; @NotNull - @Pattern(regexp = "^[a-zA-Z0-9]+$", message = "Name should contain alphabetical and numeric characters only") + @Pattern(regexp = "^[a-zA-Z0-9_]+$", message = "Name should contain alphabetical and numeric characters only") @Size(min = 1, max = 30, message = "Length of the Name should be between 1 and 30") @AttributeName(name = "gluuAttributeName") private String name; @@ -138,14 +132,6 @@ public void setInum(String inum) { this.inum = inum; } - public String getLifetime() { - return lifetime; - } - - public void setLifetime(String lifetime) { - this.lifetime = lifetime; - } - public String getSourceAttribute() { return sourceAttribute; } @@ -154,14 +140,6 @@ public void setSourceAttribute(String sourceAttribute) { this.sourceAttribute = sourceAttribute; } - public String getSalt() { - return salt; - } - - public void setSalt(String salt) { - this.salt = salt; - } - public String getNameIdType() { return nameIdType; } @@ -381,7 +359,6 @@ public int hashCode() { result = prime * result + Arrays.hashCode(editType); result = prime * result + ((gluuTooltip == null) ? 0 : gluuTooltip.hashCode()); result = prime * result + ((inum == null) ? 0 : inum.hashCode()); - result = prime * result + ((lifetime == null) ? 0 : lifetime.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((nameIdType == null) ? 0 : nameIdType.hashCode()); result = prime * result + ((origin == null) ? 0 : origin.hashCode()); @@ -389,7 +366,6 @@ public int hashCode() { result = prime * result + ((oxMultiValuedAttribute == null) ? 0 : oxMultiValuedAttribute.hashCode()); result = prime * result + ((oxSCIMCustomAttribute == null) ? 0 : oxSCIMCustomAttribute.hashCode()); result = prime * result + (requred ? 1231 : 1237); - result = prime * result + ((salt == null) ? 0 : salt.hashCode()); result = prime * result + ((saml1Uri == null) ? 0 : saml1Uri.hashCode()); result = prime * result + ((saml2Uri == null) ? 0 : saml2Uri.hashCode()); result = prime * result + ((seeAlso == null) ? 0 : seeAlso.hashCode()); diff --git a/oxService/src/main/java/org/gluu/model/LocaleSupported.java b/oxService/src/main/java/org/gluu/model/LocaleSupported.java new file mode 100644 index 000000000..c3229ef3a --- /dev/null +++ b/oxService/src/main/java/org/gluu/model/LocaleSupported.java @@ -0,0 +1,54 @@ +package org.gluu.model; + +import java.util.Objects; + +public class LocaleSupported { + + private String locale; + private String displayName; + + public LocaleSupported() { + } + + public LocaleSupported(String locale, String displayName) { + this.locale = locale; + this.displayName = displayName; + } + + public String getLocale() { + return locale; + } + public void setLocale(String locale) { + this.locale = locale; + } + + public String getDisplayName() { + return displayName; + } + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + @Override + public int hashCode() { + return Objects.hash(displayName, locale); + } + + @Override + public String toString() { + return "LocaleSupported [locale=" + locale + ", displayName=" + displayName + "]"; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + LocaleSupported other = (LocaleSupported) obj; + return Objects.equals(displayName, other.displayName) && Objects.equals(locale, other.locale); + } + +} diff --git a/oxService/src/main/java/org/gluu/model/casa/ApplicationConfiguration.java b/oxService/src/main/java/org/gluu/model/casa/ApplicationConfiguration.java new file mode 100644 index 000000000..edf26dfb5 --- /dev/null +++ b/oxService/src/main/java/org/gluu/model/casa/ApplicationConfiguration.java @@ -0,0 +1,24 @@ +package org.gluu.model.casa; + +import org.gluu.persist.annotation.AttributeName; +import org.gluu.persist.annotation.DataEntry; +import org.gluu.persist.annotation.JsonObject; +import org.gluu.persist.annotation.ObjectClass; +import org.gluu.persist.model.base.Entry; + +@DataEntry +@ObjectClass(value = "oxApplicationConfiguration") +public class ApplicationConfiguration extends Entry { + + @AttributeName(name = "oxConfApplication") + private String settings; + + public String getSettings() { + return settings; + } + + public void setSettings(String settings) { + this.settings = settings; + } + +} diff --git a/oxService/src/main/java/org/gluu/model/custom/script/type/scim/ScimType.java b/oxService/src/main/java/org/gluu/model/custom/script/type/scim/ScimType.java deleted file mode 100644 index 1c1f7f755..000000000 --- a/oxService/src/main/java/org/gluu/model/custom/script/type/scim/ScimType.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ -package org.gluu.model.custom.script.type.scim; - -import org.gluu.model.SimpleCustomProperty; -import org.gluu.model.custom.script.type.BaseExternalType; - -import java.util.Map; - -/** - * @author Val Pecaoco - */ -public interface ScimType extends BaseExternalType { - - boolean createUser(Object user, Map configurationAttributes); - - boolean postCreateUser(Object user, Map configurationAttributes); - - boolean updateUser(Object user, Map configurationAttributes); - - boolean postUpdateUser(Object user, Map configurationAttributes); - - boolean deleteUser(Object user, Map configurationAttributes); - - boolean postDeleteUser(Object user, Map configurationAttributes); - - boolean createGroup(Object user, Map configurationAttributes); - - boolean postCreateGroup(Object user, Map configurationAttributes); - - boolean updateGroup(Object user, Map configurationAttributes); - - boolean postUpdateGroup(Object user, Map configurationAttributes); - - boolean deleteGroup(Object user, Map configurationAttributes); - - boolean postDeleteGroup(Object user, Map configurationAttributes); - -} diff --git a/oxService/src/main/java/org/gluu/model/security/Group.java b/oxService/src/main/java/org/gluu/model/security/Group.java new file mode 100644 index 000000000..0d6fa465f --- /dev/null +++ b/oxService/src/main/java/org/gluu/model/security/Group.java @@ -0,0 +1,62 @@ +package org.gluu.model.security; + +import java.util.Enumeration; +import java.security.Principal; + +/** + * This interface is used to represent a group of principals. (A principal + * represents an entity such as an individual user or a company).

+ * + * Note that Group extends Principal. Thus, either a Principal or a Group can + * be passed as an argument to methods containing a Principal parameter. For + * example, you can add either a Principal or a Group to a Group object by + * calling the object's {@code addMember} method, passing it the + * Principal or Group. + * + */ +@Deprecated(since="9", forRemoval=true) +public interface Group extends Principal { + + /** + * Adds the specified member to the group. + * + * @param user the principal to add to this group. + * + * @return true if the member was successfully added, + * false if the principal was already a member. + */ + public boolean addMember(Principal user); + + /** + * Removes the specified member from the group. + * + * @param user the principal to remove from this group. + * + * @return true if the principal was removed, or + * false if the principal was not a member. + */ + public boolean removeMember(Principal user); + + /** + * Returns true if the passed principal is a member of the group. + * This method does a recursive search, so if a principal belongs to a + * group which is a member of this group, true is returned. + * + * @param member the principal whose membership is to be checked. + * + * @return true if the principal is a member of this group, + * false otherwise. + */ + public boolean isMember(Principal member); + + + /** + * Returns an enumeration of the members in the group. + * The returned objects can be instances of either Principal + * or Group (which is a subclass of Principal). + * + * @return an enumeration of the group members. + */ + public Enumeration members(); + +} diff --git a/oxService/src/main/java/org/gluu/model/security/Identity.java b/oxService/src/main/java/org/gluu/model/security/Identity.java index d5fb294d0..21e6fb0ff 100644 --- a/oxService/src/main/java/org/gluu/model/security/Identity.java +++ b/oxService/src/main/java/org/gluu/model/security/Identity.java @@ -2,25 +2,26 @@ import java.io.Serializable; import java.security.Principal; -import java.security.acl.Group; import java.util.HashMap; import javax.annotation.PostConstruct; +import javax.annotation.Priority; import javax.enterprise.context.RequestScoped; import javax.enterprise.event.Event; import javax.enterprise.inject.Alternative; import javax.inject.Inject; import javax.inject.Named; +import javax.interceptor.Interceptor; import javax.security.auth.Subject; import javax.security.auth.login.LoginException; import org.gluu.model.security.event.Authenticated; -import org.gluu.service.security.Secure; import org.slf4j.Logger; @RequestScoped @Named @Alternative +@Priority(Interceptor.Priority.APPLICATION + 10) public class Identity implements Serializable { private static final long serialVersionUID = 3751659008033189259L; @@ -226,9 +227,4 @@ public boolean hasRole(String role) { return false; } - @Secure("#{identity.loggedIn}") - public boolean checkLoggedIn() { - return isLoggedIn(); - } - } diff --git a/oxService/src/main/java/org/gluu/model/security/SimpleGroup.java b/oxService/src/main/java/org/gluu/model/security/SimpleGroup.java index fb522d06d..3e3399be5 100644 --- a/oxService/src/main/java/org/gluu/model/security/SimpleGroup.java +++ b/oxService/src/main/java/org/gluu/model/security/SimpleGroup.java @@ -2,7 +2,6 @@ import java.io.Serializable; import java.security.Principal; -import java.security.acl.Group; import java.util.Collections; import java.util.Enumeration; import java.util.HashSet; diff --git a/oxService/src/main/java/org/gluu/service/AttributeService.java b/oxService/src/main/java/org/gluu/service/AttributeService.java index b8466db9a..f0ee98075 100644 --- a/oxService/src/main/java/org/gluu/service/AttributeService.java +++ b/oxService/src/main/java/org/gluu/service/AttributeService.java @@ -34,7 +34,7 @@ public abstract class AttributeService implements Serializable { protected Logger log; @Inject - protected PersistenceEntryManager ldapEntryManager; + protected PersistenceEntryManager persistenceEntryManager; @Inject protected SchemaService schemaService; @@ -42,10 +42,13 @@ public abstract class AttributeService implements Serializable { @Inject protected CacheService cacheService; + @Inject + protected LocalCacheService localCacheService; + public List getAttributesByAttribute(String attributeName, String attributeValue, String baseDn) { String[] targetArray = new String[] { attributeValue }; Filter filter = Filter.createSubstringFilter(attributeName, null, targetArray, null); - List result = ldapEntryManager.findEntries(baseDn, GluuAttribute.class, filter); + List result = persistenceEntryManager.findEntries(baseDn, GluuAttribute.class, filter); return result; } @@ -95,22 +98,26 @@ public List getAllAttributes() { @SuppressWarnings("unchecked") public List getAllAttributes(String baseDn) { - List attributeList = (List) cacheService.get(OxConstants.CACHE_ATTRIBUTE_NAME, + BaseCacheService usedCacheService = getCacheService(); + + List attributeList = (List) usedCacheService.get(OxConstants.CACHE_ATTRIBUTE_NAME, OxConstants.CACHE_ATTRIBUTE_KEY_LIST); if (attributeList == null) { attributeList = getAllAtributesImpl(baseDn); - cacheService.put(OxConstants.CACHE_ATTRIBUTE_NAME, OxConstants.CACHE_ATTRIBUTE_KEY_LIST, attributeList); + usedCacheService.put(OxConstants.CACHE_ATTRIBUTE_NAME, OxConstants.CACHE_ATTRIBUTE_KEY_LIST, attributeList); } return attributeList; } protected List getAllAtributesImpl(String baseDn) { - List attributeList = ldapEntryManager.findEntries(baseDn, GluuAttribute.class, null); + List attributeList = persistenceEntryManager.findEntries(baseDn, GluuAttribute.class, null); return attributeList; } + protected abstract BaseCacheService getCacheService(); + public abstract String getDnForAttribute(String inum); } diff --git a/oxService/src/main/java/org/gluu/service/DataSourceTypeService.java b/oxService/src/main/java/org/gluu/service/DataSourceTypeService.java new file mode 100644 index 000000000..1da3c354f --- /dev/null +++ b/oxService/src/main/java/org/gluu/service/DataSourceTypeService.java @@ -0,0 +1,28 @@ +package org.gluu.service; + +import java.io.Serializable; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; + +import org.gluu.persist.PersistenceEntryManager; +import org.gluu.persist.cloud.spanner.impl.SpannerEntryManagerFactory; +import org.gluu.persist.ldap.impl.LdapEntryManagerFactory; + +@ApplicationScoped +public class DataSourceTypeService implements Serializable { + + private static final long serialVersionUID = -1941135478226842653L; + + @Inject + private PersistenceEntryManager entryManager; + + public boolean isSpanner(String key) { + return entryManager.getPersistenceType(key).equals(SpannerEntryManagerFactory.PERSISTENCE_TYPE); + } + + public boolean isLDAP(String key) { + return entryManager.getPersistenceType(key).equals(LdapEntryManagerFactory.PERSISTENCE_TYPE); + } + +} diff --git a/oxService/src/main/java/org/gluu/service/LocalCacheService.java b/oxService/src/main/java/org/gluu/service/LocalCacheService.java new file mode 100644 index 000000000..ce2a51d98 --- /dev/null +++ b/oxService/src/main/java/org/gluu/service/LocalCacheService.java @@ -0,0 +1,35 @@ +/* + * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2014, Gluu + */ +package org.gluu.service; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; +import javax.inject.Named; + +import org.gluu.service.cache.CacheProvider; +import org.gluu.service.cache.LocalCache; + +/** + * Provides operations with cache + * + * @author Yuriy Movchan Date: 01.24.2012 + * @author Yuriy Zabrovarnyy Date: 02.02.2017 + */ +@ApplicationScoped +@Named +public class LocalCacheService extends BaseCacheService { + + @Inject + @LocalCache + private CacheProvider cacheProvider; + + @Override + protected CacheProvider getCacheProvider() { + return cacheProvider; + } + + +} diff --git a/oxService/src/main/java/org/gluu/service/LookupService.java b/oxService/src/main/java/org/gluu/service/LookupService.java index 10ee5103d..18997be26 100644 --- a/oxService/src/main/java/org/gluu/service/LookupService.java +++ b/oxService/src/main/java/org/gluu/service/LookupService.java @@ -15,12 +15,13 @@ import javax.inject.Inject; import javax.inject.Named; +import org.apache.commons.lang3.StringUtils; import org.gluu.model.DisplayNameEntry; +import org.gluu.orm.util.StringHelper; import org.gluu.persist.PersistenceEntryManager; import org.gluu.persist.model.base.Entry; import org.gluu.search.filter.Filter; import org.gluu.util.OxConstants; -import org.slf4j.Logger; /** * Provides operations with DisplayNameEntry @@ -31,142 +32,193 @@ @Named public class LookupService implements Serializable { - private static final long serialVersionUID = -3707238475653913313L; - - @Inject - private Logger log; - - @Inject - private PersistenceEntryManager ldapEntryManager; - - @Inject - private CacheService cacheService; - - /** - * Returns DisplayNameEntry based on display name - * - * @param dn - * display name - * @return DisplayNameEntry object - */ - public DisplayNameEntry getDisplayNameEntry(String dn) throws Exception { - String key = dn; - DisplayNameEntry entry = (DisplayNameEntry) cacheService.get(OxConstants.CACHE_LOOKUP_NAME, key); - if (entry == null) { - entry = ldapEntryManager.find(key, DisplayNameEntry.class, null); - - cacheService.put(OxConstants.CACHE_LOOKUP_NAME, key, entry); - } - - return entry; - } - - /** - * Returns list of DisplayNameEntry objects - * - * @param baseDn - * base DN - * @param dns - * list of display names to find - * @return list of DisplayNameEntry objects - */ - @SuppressWarnings("unchecked") - public List getDisplayNameEntries(String baseDn, List dns) { - List inums = getInumsFromDns(dns); - if (inums.size() == 0) { - return null; - } - - String key = getCompoundKey(inums); - List entries = (List) cacheService.get(OxConstants.CACHE_LOOKUP_NAME, key); - if (entries == null) { - Filter searchFilter = buildInumFilter(inums); - - entries = ldapEntryManager.findEntries(baseDn, DisplayNameEntry.class, searchFilter); - - cacheService.put(OxConstants.CACHE_LOOKUP_NAME, key, entries); - } - - return entries; - } - - public Filter buildInumFilter(List inums) { - List inumFilters = new ArrayList(inums.size()); - for (String inum : inums) { - inumFilters.add(Filter.createEqualityFilter(OxConstants.INUM, inum)); - } - - Filter searchFilter = Filter.createORFilter(inumFilters); - - return searchFilter; - } - - public List getInumsFromDns(List dns) { - List inums = new ArrayList(); - - if (dns == null) { - return inums; - } - - for (String dn : dns) { - String inum = getInumFromDn(dn); - if (inum != null) { - inums.add(inum); - } - } - - Collections.sort(inums); - - return inums; - } - - private String getCompoundKey(List inums) { - StringBuilder compoundKey = new StringBuilder(); - for (String inum : inums) { - if (compoundKey.length() > 0) { - compoundKey.append("_"); - } - compoundKey.append(inum); - } - - return compoundKey.toString(); - } - - public List getDisplayNameEntriesByEntries(String baseDn, List entries) throws Exception { - if (entries == null) { - return null; - } - - List dns = new ArrayList(entries.size()); - for (Entry entry : entries) { - dns.add(entry.getDn()); - } - - return getDisplayNameEntries(baseDn, dns); - } - - /** - * Get inum from DN - * - * @param dn - * DN - * @return Inum - */ - public String getInumFromDn(String dn) { - if (dn == null) { - return null; - } - - if (!dn.startsWith("inum=")) { - return null; - } - - int idx = dn.indexOf(",", 5); - if (idx == -1) { - return null; - } - - return dn.substring(5, idx); - } + private static final long serialVersionUID = -3707238475653913313L; + + @Inject + private PersistenceEntryManager persistenceEntryManager; + + @Inject + private CacheService cacheService; + + /** + * Returns DisplayNameEntry based on display name + * + * @param dn + * display name + * @return DisplayNameEntry object + */ + public DisplayNameEntry getDisplayNameEntry(String dn, String objectClass) throws Exception { + String key = "l_" + objectClass + "_" + dn; + DisplayNameEntry entry = (DisplayNameEntry) cacheService.get(OxConstants.CACHE_LOOKUP_NAME, key); + if (entry == null) { + // Prepare sample for search + DisplayNameEntry sample = new DisplayNameEntry(); + sample.setBaseDn(dn); + sample.setCustomObjectClasses(new String[] { objectClass }); + + List entries = persistenceEntryManager.findEntries(sample, 1); + if (entries.size() == 1) { + entry = entries.get(0); + } + + cacheService.put(OxConstants.CACHE_LOOKUP_NAME, key, entry); + } + + return entry; + } + + public T getDisplayNameEntry(String dn, Class entryClass) throws Exception { + String key = "l_" + entryClass.getSimpleName() + "_" + dn; + T entry = (T) cacheService.get(OxConstants.CACHE_LOOKUP_NAME, key); + if (entry == null) { + entry = persistenceEntryManager.find(dn, entryClass, null); + + cacheService.put(OxConstants.CACHE_LOOKUP_NAME, key, entry); + } + + return entry; + } + + @Deprecated + public DisplayNameEntry getDisplayNameEntry(String dn) throws Exception { + return getDisplayNameEntry(dn, DisplayNameEntry.class); + } + + /** + * Returns DisplayNameEntry based on display name + * + * @param dn + * display name + * @return DisplayNameEntry object + */ + public Object getTypedEntry(String dn, String clazz) throws Exception { + if (StringUtils.isEmpty(clazz)) { + return null; + } + + Class entryClass = Class.class.forName(clazz); + String key = "l_" + entryClass.getSimpleName() + "_" + dn; + Object entry = cacheService.get(OxConstants.CACHE_LOOKUP_NAME, key); + if (entry == null) { + entry = persistenceEntryManager.find(entryClass, dn); + + cacheService.put(OxConstants.CACHE_LOOKUP_NAME, key, entry); + } + + return entry; + } + + /** + * Returns list of DisplayNameEntry objects + * + * @param baseDn + * base DN + * @param dns + * list of display names to find + * @return list of DisplayNameEntry objects + */ + @SuppressWarnings("unchecked") + public List getDisplayNameEntries(String baseDn, Class entryClass, List dns) { + List inums = getInumsFromDns(dns); + if (inums.size() == 0) { + return null; + } + + String key = getCompoundKey(entryClass, inums); + List entries = (List) cacheService.get(OxConstants.CACHE_LOOKUP_NAME, key); + if (entries == null) { + Filter searchFilter = buildInumFilter(inums); + entries = persistenceEntryManager.findEntries(baseDn, entryClass, searchFilter); + cacheService.put(OxConstants.CACHE_LOOKUP_NAME, key, entries); + } + return entries; + } + + @Deprecated + public List getDisplayNameEntries(String baseDn, List dns) { + return getDisplayNameEntries(baseDn, DisplayNameEntry.class, dns); + } + + public Filter buildInumFilter(List inums) { + List inumFilters = new ArrayList(inums.size()); + for (String inum : inums) { + inumFilters.add(Filter.createEqualityFilter(OxConstants.INUM, inum).multiValued(false)); + } + return Filter.createORFilter(inumFilters); + } + + public List getInumsFromDns(List dns) { + List inums = new ArrayList(); + + if (dns == null) { + return inums; + } + + for (String dn : dns) { + String inum = getInumFromDn(dn); + if (inum != null) { + inums.add(inum); + } + } + + Collections.sort(inums); + + return inums; + } + + private String getCompoundKey(Class entryClass, List inums) { + StringBuilder compoundKey = new StringBuilder(); + for (String inum : inums) { + if (compoundKey.length() > 0) { + compoundKey.append("_"); + } else { + compoundKey.append("l_" + entryClass.getSimpleName() + "_"); + } + compoundKey.append(inum); + } + + return compoundKey.toString(); + } + + public List getDisplayNameEntriesByEntries(String baseDn, List entries) + throws Exception { + if (entries == null) { + return null; + } + + Class objectClass = DisplayNameEntry.class; + List dns = new ArrayList(entries.size()); + for (Entry entry : entries) { + dns.add(entry.getDn()); + objectClass = objectClass.getClass(); + } + + + return getDisplayNameEntries(baseDn, objectClass, dns); + } + + /** + * Get inum from DN + * + * @param dn + * DN + * @return Inum + */ + public String getInumFromDn(String dn) { + if (dn == null) { + return null; + } + + if (!dn.startsWith("inum=")) { + return null; + } + + int idx = dn.indexOf(",", 5); + if (idx == -1) { + return null; + } + + return dn.substring(5, idx); + } } diff --git a/oxService/src/main/java/org/gluu/service/MailService.java b/oxService/src/main/java/org/gluu/service/MailService.java index d77c8cba7..93c1892c2 100644 --- a/oxService/src/main/java/org/gluu/service/MailService.java +++ b/oxService/src/main/java/org/gluu/service/MailService.java @@ -2,11 +2,27 @@ * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. * * Copyright (c) 2014, Gluu - */package org.gluu.service; + */ +package org.gluu.service; +import java.io.FileInputStream; +import java.io.InputStream; +import java.security.InvalidParameterException; +import java.security.KeyStore; +import java.security.PrivateKey; +import java.security.cert.Certificate; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateParsingException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Date; +import java.util.List; import java.util.Properties; +import javax.activation.CommandMap; +import javax.activation.MailcapCommandMap; +import javax.annotation.PostConstruct; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; import javax.inject.Named; @@ -20,8 +36,25 @@ import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; +import org.apache.commons.io.FilenameUtils; +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.cms.AttributeTable; +import org.bouncycastle.asn1.smime.SMIMECapabilitiesAttribute; +import org.bouncycastle.asn1.smime.SMIMECapability; +import org.bouncycastle.asn1.smime.SMIMECapabilityVector; +import org.bouncycastle.asn1.smime.SMIMEEncryptionKeyPreferenceAttribute; +import org.bouncycastle.cert.jcajce.JcaCertStore; +import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder; +import org.bouncycastle.mail.smime.SMIMEException; +import org.bouncycastle.mail.smime.SMIMESignedGenerator; +import org.bouncycastle.mail.smime.SMIMEUtil; +import org.bouncycastle.operator.OperatorCreationException; + import org.gluu.model.SmtpConfiguration; +import org.gluu.model.SmtpConnectProtectionType; import org.gluu.util.StringHelper; +import org.gluu.util.security.SecurityProviderUtility; + import org.slf4j.Logger; /** @@ -39,8 +72,45 @@ public class MailService { @Inject private SmtpConfiguration smtpConfiguration; + private KeyStore keyStore; + private long connectionTimeout = 5000; + @PostConstruct + public void init() { + MailcapCommandMap mc = (MailcapCommandMap) CommandMap.getDefaultCommandMap(); + mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html"); + mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml"); + mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain"); + mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed"); + mc.addMailcap("message/rfc822;; x-java-content- handler=com.sun.mail.handlers.message_rfc822"); + + String keystoreFile = smtpConfiguration.getKeyStore(); + String keystoreSecret = smtpConfiguration.getKeyStorePasswordDecrypted(); + + SecurityProviderUtility.KeyStorageType keystoreType = solveKeyStorageType(keystoreFile); + + try(InputStream is = new FileInputStream(keystoreFile)) { + switch (keystoreType) { + case JKS_KS: { + keyStore = KeyStore.getInstance("JKS"); + break; + } + case PKCS12_KS: { + keyStore = KeyStore.getInstance("PKCS12", SecurityProviderUtility.getBCProvider()); + break; + } + case BCFKS_KS: { + keyStore = KeyStore.getInstance("BCFKS", SecurityProviderUtility.getBCProvider()); + break; + } + } + keyStore.load(is, keystoreSecret.toCharArray()); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + } + public boolean sendMail(String to, String subject, String message) { return sendMail(smtpConfiguration, null, null, to, null, subject, message, null); } @@ -82,12 +152,20 @@ public boolean sendMail(SmtpConfiguration mailSmtpConfiguration, String from, St props.put("mail.smtp.connectiontimeout", this.connectionTimeout); props.put("mail.smtp.timeout", this.connectionTimeout); props.put("mail.transport.protocol", "smtp"); - props.put("mail.smtp.ssl.trust", mailSmtpConfiguration.getHost()); - if (mailSmtpConfiguration.isRequiresSsl()) { + SmtpConnectProtectionType smtpConnectProtect = mailSmtpConfiguration.getConnectProtection(); + + if (smtpConnectProtect == SmtpConnectProtectionType.START_TLS) { + props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); props.put("mail.smtp.socketFactory.port", mailSmtpConfiguration.getPort()); + props.put("mail.smtp.ssl.trust", mailSmtpConfiguration.getHost()); props.put("mail.smtp.starttls.enable", true); + } + else if (smtpConnectProtect == SmtpConnectProtectionType.SSL_TLS) { props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); + props.put("mail.smtp.socketFactory.port", mailSmtpConfiguration.getPort()); + props.put("mail.smtp.ssl.trust", mailSmtpConfiguration.getHost()); + props.put("mail.smtp.ssl.enable", true); } Session session = null; @@ -103,7 +181,167 @@ protected PasswordAuthentication getPasswordAuthentication() { } }); } else { - Session.getInstance(props, null); + session = Session.getInstance(props, null); + } + + MimeMessage msg = new MimeMessage(session); + try { + msg.setFrom(new InternetAddress(mailFrom, mailFromName)); + if (StringHelper.isEmpty(toDisplayName)) { + msg.setRecipients(Message.RecipientType.TO, to); + } else { + msg.addRecipient(Message.RecipientType.TO, new InternetAddress(to, toDisplayName)); + } + msg.setSubject(subject, "UTF-8"); + msg.setSentDate(new Date()); + + if (StringHelper.isEmpty(htmlMessage)) { + msg.setText(message + "\n", "UTF-8", "plain"); + } else { + // Unformatted text version + final MimeBodyPart textPart = new MimeBodyPart(); + textPart.setText(message, "UTF-8", "plain"); + // HTML version + final MimeBodyPart htmlPart = new MimeBodyPart(); + htmlPart.setText(htmlMessage, "UTF-8", "html"); + + // Create the Multipart. Add BodyParts to it. + final Multipart mp = new MimeMultipart("alternative"); + mp.addBodyPart(textPart); + mp.addBodyPart(htmlPart); + + // Set Multipart as the message's content + msg.setContent(mp); + } + + Transport.send(msg); + } catch (Exception ex) { + log.error("Failed to send message", ex); + return false; + } + + return true; + } + + public boolean sendMailSigned(String to, String subject, String message) { + return sendMailSigned(smtpConfiguration, null, null, to, null, subject, message, null); + } + + public boolean sendMailSigned(String to, String toDisplayName, String subject, String message, String htmlMessage) { + return sendMailSigned(smtpConfiguration, null, null, to, null, subject, message, htmlMessage); + } + + public boolean sendMailSigned(String from, String fromDisplayName, String to, String toDisplayName, String subject, + String message, String htmlMessage) { + return sendMailSigned(smtpConfiguration, from, fromDisplayName, to, null, subject, message, htmlMessage); + } + + public boolean sendMailSigned(SmtpConfiguration mailSmtpConfiguration, String from, String fromDisplayName, String to, + String toDisplayName, + String subject, String message, String htmlMessage) { + if (mailSmtpConfiguration == null) { + log.error("Failed to send message from '{}' to '{}' because the SMTP configuration isn't valid!", from, to); + return false; + } + + log.debug("Host name: " + mailSmtpConfiguration.getHost() + ", port: " + mailSmtpConfiguration.getPort() + ", connection time out: " + + this.connectionTimeout); + + PrivateKey privateKey = null; + + Certificate[] certificates = null; + X509Certificate[] x509Certificates = null; + + try { + privateKey = (PrivateKey)keyStore.getKey(mailSmtpConfiguration.getKeyStoreAlias(), + smtpConfiguration.getKeyStorePasswordDecrypted().toCharArray()); + certificates = keyStore.getCertificateChain(mailSmtpConfiguration.getKeyStoreAlias()); + if (certificates != null) { + x509Certificates = new X509Certificate[certificates.length]; + for (int i = 0; i < certificates.length; i++) { + x509Certificates[i] = (X509Certificate)certificates[i]; + } + } + } catch (Exception e) { + log.error(e.getMessage()); + } + + String mailFrom = from; + if (StringHelper.isEmpty(mailFrom)) { + mailFrom = mailSmtpConfiguration.getFromEmailAddress(); + } + + String mailFromName = fromDisplayName; + if (StringHelper.isEmpty(mailFromName)) { + mailFromName = mailSmtpConfiguration.getFromName(); + } + + Properties props = new Properties(); + + props.put("mail.from", mailFrom); + + SmtpConnectProtectionType smtpConnectProtect = mailSmtpConfiguration.getConnectProtection(); + + if (smtpConnectProtect == SmtpConnectProtectionType.START_TLS) { + props.put("mail.transport.protocol", "smtp"); + + props.put("mail.smtp.host", mailSmtpConfiguration.getHost()); + props.put("mail.smtp.port", mailSmtpConfiguration.getPort()); + props.put("mail.smtp.connectiontimeout", this.connectionTimeout); + props.put("mail.smtp.timeout", this.connectionTimeout); + + props.put("mail.smtp.socketFactory.class", "com.sun.mail.util.MailSSLSocketFactory"); + props.put("mail.smtp.socketFactory.port", mailSmtpConfiguration.getPort()); + if (mailSmtpConfiguration.isServerTrust()) { + props.put("mail.smtp.ssl.trust", mailSmtpConfiguration.getHost()); + } + props.put("mail.smtp.starttls.enable", true); + props.put("mail.smtp.starttls.required", true); + } + else if (smtpConnectProtect == SmtpConnectProtectionType.SSL_TLS) { + props.put("mail.transport.protocol.rfc822", "smtps"); + + props.put("mail.smtps.host", mailSmtpConfiguration.getHost()); + props.put("mail.smtps.port", mailSmtpConfiguration.getPort()); + props.put("mail.smtps.connectiontimeout", this.connectionTimeout); + props.put("mail.smtps.timeout", this.connectionTimeout); + + props.put("mail.smtp.socketFactory.class", "com.sun.mail.util.MailSSLSocketFactory"); + props.put("mail.smtp.socketFactory.port", mailSmtpConfiguration.getPort()); + if (mailSmtpConfiguration.isServerTrust()) { + props.put("mail.smtp.ssl.trust", mailSmtpConfiguration.getHost()); + } + props.put("mail.smtp.ssl.enable", true); + } + else { + props.put("mail.transport.protocol", "smtp"); + + props.put("mail.smtp.host", mailSmtpConfiguration.getHost()); + props.put("mail.smtp.port", mailSmtpConfiguration.getPort()); + props.put("mail.smtp.connectiontimeout", this.connectionTimeout); + props.put("mail.smtp.timeout", this.connectionTimeout); + } + + Session session = null; + if (mailSmtpConfiguration.isRequiresAuthentication()) { + + if (smtpConnectProtect == SmtpConnectProtectionType.SSL_TLS) { + props.put("mail.smtps.auth", "true"); + } + else { + props.put("mail.smtp.auth", "true"); + } + + final String userName = mailSmtpConfiguration.getUserName(); + final String password = mailSmtpConfiguration.getPasswordDecrypted(); + + session = Session.getInstance(props, new javax.mail.Authenticator() { + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(userName, password); + } + }); + } else { + session = Session.getInstance(props, null); } MimeMessage msg = new MimeMessage(session); @@ -134,6 +372,10 @@ protected PasswordAuthentication getPasswordAuthentication() { // Set Multipart as the message's content msg.setContent(mp); + + MimeMultipart multiPart = createMultipartWithSignature(privateKey, x509Certificates, smtpConfiguration.getSigningAlgorithm(), msg); + + msg.setContent(multiPart); } Transport.send(msg); @@ -153,4 +395,115 @@ public void setConnectionTimeout(long connectionTimeout) { this.connectionTimeout = connectionTimeout; } + /** + * @param cert + * @return + * @throws CertificateParsingException + */ + private static ASN1EncodableVector generateSignedAttributes(X509Certificate cert) throws CertificateParsingException { + ASN1EncodableVector signedAttrs = new ASN1EncodableVector(); + SMIMECapabilityVector caps = new SMIMECapabilityVector(); + caps.addCapability(SMIMECapability.aES256_CBC); + caps.addCapability(SMIMECapability.dES_EDE3_CBC); + caps.addCapability(SMIMECapability.rC2_CBC, 128); + signedAttrs.add(new SMIMECapabilitiesAttribute(caps)); + signedAttrs.add(new SMIMEEncryptionKeyPreferenceAttribute(SMIMEUtil.createIssuerAndSerialNumberFor(cert))); + return signedAttrs; + } + + /** + * + * @param key + * @param cert + * @param signingAlgorithm + * @param dataPart + * @return + * @throws CertificateEncodingException + * @throws CertificateParsingException + * @throws OperatorCreationException + * @throws SMIMEException + */ + public static MimeMultipart createMultipartWithSignature(PrivateKey key, X509Certificate cert, String signingAlgorithm, MimeMessage mm) throws CertificateEncodingException, CertificateParsingException, OperatorCreationException, SMIMEException { + List certList = new ArrayList(); + certList.add(cert); + + JcaCertStore certs = new JcaCertStore(certList); + ASN1EncodableVector signedAttrs = generateSignedAttributes(cert); + + SMIMESignedGenerator gen = new SMIMESignedGenerator(); + + if (signingAlgorithm == null || signingAlgorithm.isEmpty()) { + signingAlgorithm = cert.getSigAlgName(); + } + + gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider(SecurityProviderUtility.getBCProvider()).setSignedAttributeGenerator(new AttributeTable(signedAttrs)).build(signingAlgorithm, key, cert)); + + gen.addCertificates(certs); + + return gen.generate(mm); + } + + /** + * + * @param key + * @param inCerts + * @param signingAlgorithm + * @param mm + * @return + * @throws CertificateEncodingException + * @throws CertificateParsingException + * @throws OperatorCreationException + * @throws SMIMEException + */ + public static MimeMultipart createMultipartWithSignature(PrivateKey key, X509Certificate[] inCerts, String signingAlgorithm, MimeMessage mm) throws CertificateEncodingException, CertificateParsingException, OperatorCreationException, SMIMEException { + + JcaCertStore certs = new JcaCertStore(Arrays.asList(inCerts)); + ASN1EncodableVector signedAttrs = generateSignedAttributes((X509Certificate)inCerts[0]); + + SMIMESignedGenerator gen = new SMIMESignedGenerator(); + + if (signingAlgorithm == null || signingAlgorithm.isEmpty()) { + signingAlgorithm = ((X509Certificate)inCerts[0]).getSigAlgName(); + } + + gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider(SecurityProviderUtility.getBCProvider()).setSignedAttributeGenerator(new AttributeTable(signedAttrs)).build(signingAlgorithm, key, (X509Certificate)inCerts[0])); + + gen.addCertificates(certs); + + return gen.generate(mm); + } + + /** + * + * @return + */ + private SecurityProviderUtility.KeyStorageType solveKeyStorageType(final String keyStoreFile) { + SecurityProviderUtility.SecurityModeType securityMode = SecurityProviderUtility.getSecurityMode(); + if (securityMode == null) { + throw new InvalidParameterException("Security Mode wasn't initialized. Call installBCProvider() before"); + } + String keyStoreExt = FilenameUtils.getExtension(keyStoreFile); + SecurityProviderUtility.KeyStorageType keyStorageType = SecurityProviderUtility.KeyStorageType.fromExtension(keyStoreExt); + boolean ksTypeFound = false; + for (SecurityProviderUtility.KeyStorageType ksType : securityMode.getKeystorageTypes()) { + if (keyStorageType == ksType) { + ksTypeFound = true; + break; + } + } + if (!ksTypeFound) { + switch (securityMode) { + case BCFIPS_SECURITY_MODE: { + keyStorageType = SecurityProviderUtility.KeyStorageType.BCFKS_KS; + break; + } + case BCPROV_SECURITY_MODE: { + keyStorageType = SecurityProviderUtility.KeyStorageType.PKCS12_KS; + break; + } + } + } + return keyStorageType; + } + } diff --git a/oxService/src/main/java/org/gluu/service/ObjectSerializationService.java b/oxService/src/main/java/org/gluu/service/ObjectSerializationService.java index 27e377bcc..c0343aa3a 100644 --- a/oxService/src/main/java/org/gluu/service/ObjectSerializationService.java +++ b/oxService/src/main/java/org/gluu/service/ObjectSerializationService.java @@ -20,7 +20,6 @@ import javax.inject.Named; import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; import org.apache.commons.lang.SerializationUtils; import org.slf4j.Logger; @@ -33,75 +32,66 @@ @Named public class ObjectSerializationService { - @Inject - private Logger log; - - public boolean saveObject(String path, Serializable obj, boolean append) { - File file = new File(path); - FileOutputStream fos; - try { - fos = new FileOutputStream(file, append); - } catch (FileNotFoundException ex) { - log.error("Faield to serialize to file: '{}'. Error: ", path, ex); - - return false; - } - - BufferedOutputStream bos = new BufferedOutputStream(fos); - try { - GZIPOutputStream gos = new GZIPOutputStream(bos); - SerializationUtils.serialize(obj, gos); - gos.flush(); - IOUtils.closeQuietly(gos); - } catch (IOException ex) { - log.error("Faield to serialize to file: '{}'. Error: ", path, ex); - IOUtils.closeQuietly(bos); - - return false; - } - - return true; - } - - public boolean saveObject(String path, Serializable obj) { - return saveObject(path, obj, false); - } - - public Object loadObject(String path) { - File file = new File(path); - if (!file.exists()) { - log.trace("File '{}' is not exist", path); - return null; - } - - FileInputStream fis; - try { - fis = new FileInputStream(file); - } catch (FileNotFoundException ex) { - log.error("Faield to deserialize from file: '{}'. Error: ", path, ex); - - return null; - } - - BufferedInputStream bis = new BufferedInputStream(fis); - Object obj = null; - try { - GZIPInputStream gis = new GZIPInputStream(bis); - obj = SerializationUtils.deserialize(gis); - IOUtils.closeQuietly(gis); - } catch (IOException ex) { - log.error("Faield to deserialize from file: '{}'. Error: ", path, ex); - IOUtils.closeQuietly(bis); - - return null; - } - - return obj; - } - - public void cleanup(String path) { - File file = new File(path); - FileUtils.deleteQuietly(file); - } + @Inject + private Logger log; + + public boolean saveObject(String path, Serializable obj, boolean append) { + File file = new File(path); + FileOutputStream fos; + try { + fos = new FileOutputStream(file, append); + } catch (FileNotFoundException ex) { + log.error("Faield to serialize to file: '{}'. Error: ", path, ex); + + return false; + } + + ; + try (GZIPOutputStream gos = new GZIPOutputStream(new BufferedOutputStream(fos))) { + SerializationUtils.serialize(obj, gos); + gos.flush(); + } catch (IOException ex) { + log.error("Faield to serialize to file: '{}'. Error: ", path, ex); + return false; + } + + return true; + } + + public boolean saveObject(String path, Serializable obj) { + return saveObject(path, obj, false); + } + + public Object loadObject(String path) { + File file = new File(path); + if (!file.exists()) { + log.trace("File '{}' is not exist", path); + return null; + } + + FileInputStream fis; + try { + fis = new FileInputStream(file); + } catch (FileNotFoundException ex) { + log.error("Faield to deserialize from file: '{}'. Error: ", path, ex); + + return null; + } + + Object obj = null; + try (GZIPInputStream gis = new GZIPInputStream(new BufferedInputStream(fis))) { + ; + obj = SerializationUtils.deserialize(gis); + } catch (IOException ex) { + log.error("Faield to deserialize from file: '{}'. Error: ", path, ex); + return null; + } + return obj; + } + + public void cleanup(String path) { + File file = new File(path); + FileUtils.deleteQuietly(file); + } } diff --git a/oxService/src/main/java/org/gluu/service/OrganizationService.java b/oxService/src/main/java/org/gluu/service/OrganizationService.java index 11efdf2a7..8a26dfadd 100644 --- a/oxService/src/main/java/org/gluu/service/OrganizationService.java +++ b/oxService/src/main/java/org/gluu/service/OrganizationService.java @@ -9,6 +9,8 @@ import java.io.Serializable; +import org.gluu.model.ApplicationType; + /** * @author "Oleksiy Tataryn" * @@ -17,6 +19,8 @@ public abstract class OrganizationService implements Serializable { private static final long serialVersionUID = -6601700282123372943L; + public static final int ONE_MINUTE_IN_SECONDS = 60; + public String getDnForOrganization(String baseDn) { if (baseDn == null) { baseDn = "o=gluu"; @@ -24,4 +28,5 @@ public String getDnForOrganization(String baseDn) { return baseDn; } + public abstract ApplicationType getApplicationType(); } diff --git a/oxService/src/main/java/org/gluu/service/SchemaService.java b/oxService/src/main/java/org/gluu/service/SchemaService.java index efdb84249..60d061f15 100644 --- a/oxService/src/main/java/org/gluu/service/SchemaService.java +++ b/oxService/src/main/java/org/gluu/service/SchemaService.java @@ -20,6 +20,8 @@ import org.gluu.model.SchemaEntry; import org.gluu.persist.PersistenceEntryManager; +import org.gluu.orm.hybrid.impl.HybridEntryManagerFactory; +import org.gluu.persist.ldap.impl.LdapEntryManagerFactory; import org.gluu.persist.ldap.operation.LdapOperationService; import org.gluu.util.StringHelper; import org.gluu.util.exception.InvalidSchemaUpdateException; @@ -41,7 +43,14 @@ public class SchemaService { private Logger log; @Inject - private PersistenceEntryManager ldapEntryManager; + private PersistenceEntryManager persistenceEntryManager; + + + @Inject + private DataSourceTypeService dataSourceTypeService; + + @Inject + private AttributeService attributeService; /** * Load schema from DS @@ -51,7 +60,8 @@ public class SchemaService { public SchemaEntry getSchema() { String shemaDn = getDnForSchema(); if (StringHelper.isNotEmpty(shemaDn)) { - SchemaEntry schemaEntry = ldapEntryManager.find(getDnForSchema(), SchemaEntry.class, null); + PersistenceEntryManager ldapPersistenceEntryManager = getPersistenceEntryManager(); + SchemaEntry schemaEntry = ldapPersistenceEntryManager.find(getDnForSchema(), SchemaEntry.class, null); return schemaEntry; } @@ -81,7 +91,8 @@ public void addObjectClass(String objectClass, String attributeTypes, String sch schemaEntry.addObjectClass(objectClassDefinition); log.debug("Adding new objectClass: {}", schemaEntry); - ldapEntryManager.merge(schemaEntry); + PersistenceEntryManager ldapPersistenceEntryManager = getPersistenceEntryManager(); + ldapPersistenceEntryManager.merge(schemaEntry); } /** @@ -105,7 +116,8 @@ private void removeObjectClassWithDefinition(String objectClassDefinition) { schemaEntry.addObjectClass(objectClassDefinition); log.debug("Removing objectClass: {}", schemaEntry); - ldapEntryManager.remove(schemaEntry); + PersistenceEntryManager ldapPersistenceEntryManager = getPersistenceEntryManager(); + ldapPersistenceEntryManager.remove(schemaEntry); } /** @@ -159,7 +171,8 @@ public void addAttributeTypeToObjectClass(String objectClass, String attributeTy newSchemaEntry.addObjectClass(newObjectClassDefinition); log.debug("Adding attributeType to objectClass: {}", newSchemaEntry); - ldapEntryManager.merge(newSchemaEntry); + PersistenceEntryManager ldapPersistenceEntryManager = getPersistenceEntryManager(); + ldapPersistenceEntryManager.merge(newSchemaEntry); } /** @@ -206,7 +219,8 @@ public void removeAttributeTypeFromObjectClass(String objectClass, String attrib schemaEntry.addObjectClass(newObjectClassDefinition); log.debug("Removing attributeType from objectClass: {}", schemaEntry); - ldapEntryManager.merge(schemaEntry); + PersistenceEntryManager ldapPersistenceEntryManager = getPersistenceEntryManager(); + ldapPersistenceEntryManager.merge(schemaEntry); } @@ -225,7 +239,8 @@ public void addStringAttribute(String oid, String name, String schemaAddAttribut schemaEntry.addAttributeType(String.format(schemaAddAttributeDefinition, oid, name)); log.debug("Adding new attributeType: {}", schemaEntry); log.info("merging data"); - ldapEntryManager.merge(schemaEntry); + PersistenceEntryManager ldapPersistenceEntryManager = getPersistenceEntryManager(); + ldapPersistenceEntryManager.merge(schemaEntry); } /** @@ -245,7 +260,8 @@ public void removeStringAttribute(String attributeType) throws Exception { schemaEntry.addAttributeType(attributeTypeDefinition); log.debug("Removing attributeType: {}", schemaEntry); - ldapEntryManager.remove(schemaEntry); + PersistenceEntryManager ldapPersistenceEntryManager = getPersistenceEntryManager(); + ldapPersistenceEntryManager.remove(schemaEntry); } } @@ -495,11 +511,24 @@ public Set getObjectClassesByAttribute(SchemaEntry schemaEntry, String a * @return DN string for DS schema */ public String getDnForSchema() { - if (ldapEntryManager.getOperationService() instanceof LdapOperationService) { - return ((LdapOperationService) ldapEntryManager.getOperationService()).getSubschemaSubentry(); + PersistenceEntryManager ldapPersistenceEntryManager = getPersistenceEntryManager(); + if (ldapPersistenceEntryManager != null) { + return ((LdapOperationService) ldapPersistenceEntryManager.getOperationService()).getSubschemaSubentry(); } else { return ""; } } + + private PersistenceEntryManager getPersistenceEntryManager() { + if (dataSourceTypeService.isLDAP(attributeService.getDnForAttribute(null))) { + if (persistenceEntryManager.getPersistenceType().equals(HybridEntryManagerFactory.PERSISTENCE_TYPE)) { + return persistenceEntryManager.getPersistenceEntryManager(LdapEntryManagerFactory.PERSISTENCE_TYPE); + } + + return persistenceEntryManager; + } + + return null; + } } diff --git a/oxService/src/main/java/org/gluu/service/XmlService.java b/oxService/src/main/java/org/gluu/service/XmlService.java index 6433fa516..e25ca7d43 100644 --- a/oxService/src/main/java/org/gluu/service/XmlService.java +++ b/oxService/src/main/java/org/gluu/service/XmlService.java @@ -5,19 +5,12 @@ */package org.gluu.service; import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.Serializable; +import java.nio.charset.Charset; -import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; -import javax.inject.Named; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; -import javax.xml.bind.Unmarshaller; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPath; @@ -27,8 +20,6 @@ import javax.xml.xpath.XPathFactory; import org.apache.commons.io.IOUtils; -import org.gluu.model.GluuImage; -import org.gluu.model.TrustContact; import org.gluu.util.StringHelper; import org.slf4j.Logger; import org.w3c.dom.Document; @@ -42,127 +33,26 @@ * @author Yuriy Movchan Date: 01.11.2011 */ @ApplicationScoped -@Named -public class XmlService implements Serializable { +public class XmlService { private static final long serialVersionUID = -4805285557592935972L; @Inject private Logger log; - private JAXBContext jaxbContext; - private Marshaller jaxbMarshaller; - private Unmarshaller jaxbUnmarshaller; - - @PostConstruct - public void init() { - try { - this.jaxbContext = JAXBContext.newInstance(GluuImage.class, TrustContact.class); - this.jaxbMarshaller = this.jaxbContext.createMarshaller(); - this.jaxbUnmarshaller = this.jaxbContext.createUnmarshaller(); - } catch (JAXBException ex) { - log.error("Failed to create JAXB marshaller and unmarshaller", ex); - } - } - - public String getXMLFromGluuImage(GluuImage photo) { - if (photo == null) { - return null; - } - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - try { - this.jaxbMarshaller.marshal(photo, bos); - return new String(bos.toByteArray(), "UTF-8"); - } catch (Exception ex) { - log.error("Failed to convert GluuImage {} to XML", ex, photo); - } - - return null; - } - - public GluuImage getGluuImageFromXML(String xml) { - if (xml == null) { - return null; - } - - try { - ByteArrayInputStream bis = new ByteArrayInputStream(xml.getBytes("UTF-8")); - return (GluuImage) this.jaxbUnmarshaller.unmarshal(bis); - } catch (Exception ex) { - log.error("Failed to create GluuImage from XML {}", ex, xml); - } - - return null; + public Document getXmlDocument(String xmlDocument) throws SAXException, IOException, ParserConfigurationException { + return getXmlDocument(xmlDocument, false); } - public TrustContact getTrustContactFromXML(String xml) { - if (xml == null) { - return null; - } - + public Document getXmlDocument(String xmlDocument, boolean skipValidation) throws SAXException, IOException, ParserConfigurationException { + InputStream is = IOUtils.toInputStream(xmlDocument, Charset.forName("utf-8")); try { - ByteArrayInputStream bis = new ByteArrayInputStream(xml.getBytes("UTF-8")); - return (TrustContact) this.jaxbUnmarshaller.unmarshal(bis); - } catch (Exception ex) { - log.error("Failed to create TrustContact from XML {}", ex, xml); - } - - return null; - } - - // public String - // getXMLFromDeconstructedTrustRelationship(DeconstructedTrustRelationship - // deconstructedTR) { - // if (deconstructedTR == null) { - // return null; - // } - // - // ByteArrayOutputStream bos = new ByteArrayOutputStream(); - // try { - // this.jaxbMarshaller.marshal(deconstructedTR, bos); - // return new String(bos.toByteArray(), "UTF-8"); - // } catch (Exception ex) { - // log.error("Failed to convert DeconstructedTrustRelationship {} to XML", - // ex, deconstructedTR); - // } - // - // return null; - // } - // - // public DeconstructedTrustRelationship - // getDeconstructedTrustRelationshipFromXML(String xml) { - // if (xml == null) { - // return null; - // } - // - // try { - // ByteArrayInputStream bis = new - // ByteArrayInputStream(xml.getBytes("UTF-8")); - // return (DeconstructedTrustRelationship) - // this.jaxbUnmarshaller.unmarshal(bis); - // } catch (Exception ex) { - // log.error("Failed to create DeconstructedTrustRelationship from XML {}", - // ex, xml); - // } - // - // return null; - // } - - public String getXMLFromTrustContact(TrustContact contact) { - if (contact == null) { - return null; - } + DocumentBuilderFactory fty = createDocumentBuilderFactory(skipValidation); - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - try { - this.jaxbMarshaller.marshal(contact, bos); - return new String(bos.toByteArray(), "UTF-8"); - } catch (Exception ex) { - log.error("Failed to convert TrustContact {} to XML", ex, contact); + return fty.newDocumentBuilder().parse(is); + } finally { + IOUtils.closeQuietly(is); } - - return null; } public Document getXmlDocument(byte[] xmlDocumentBytes) throws SAXException, IOException, ParserConfigurationException { @@ -192,7 +82,7 @@ public Document getXmlDocument(InputSource is) throws SAXException, IOException, return fty.newDocumentBuilder().parse(is); } - public Document getXmlDocument(String uri) throws SAXException, IOException, ParserConfigurationException { + public Document getXmlDocumentFromUri(String uri) throws SAXException, IOException, ParserConfigurationException { DocumentBuilderFactory fty = createDocumentBuilderFactory(); return fty.newDocumentBuilder().parse(uri); @@ -238,6 +128,12 @@ public String getNodeValue(Document xmlDocument, String xPathExpression, String Node attributeNode = node.getAttributes().getNamedItem(attributeName); if (attributeNode == null) { + if (node.getChildNodes().getLength() == 1) { + node = node.getFirstChild(); + if (node.getNodeType() == Node.TEXT_NODE) { + return node.getNodeValue(); + } + } return null; } diff --git a/oxService/src/main/java/org/gluu/service/cache/NativePersistenceCacheEntity.java b/oxService/src/main/java/org/gluu/service/cache/NativePersistenceCacheEntity.java deleted file mode 100644 index 906d6d5e2..000000000 --- a/oxService/src/main/java/org/gluu/service/cache/NativePersistenceCacheEntity.java +++ /dev/null @@ -1,88 +0,0 @@ -package org.gluu.service.cache; - -import org.gluu.persist.model.base.Deletable; -import org.gluu.persist.annotation.AttributeName; -import org.gluu.persist.annotation.DN; -import org.gluu.persist.annotation.DataEntry; -import org.gluu.persist.annotation.ObjectClass; - -import java.io.Serializable; -import java.util.Date; - -@DataEntry -@ObjectClass(value = "cache") -public class NativePersistenceCacheEntity implements Serializable, Deletable { - - @DN - private String dn; - @AttributeName(name = "uuid") - private String id; - @AttributeName(name = "iat") - private Date creationDate; - @AttributeName(name = "exp") - private Date expirationDate; - @AttributeName(name = "del") - private boolean deletable = true; - @AttributeName(name = "dat") - private String data; - - public String getDn() { - return dn; - } - - public void setDn(String dn) { - this.dn = dn; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public Date getCreationDate() { - return creationDate; - } - - public void setCreationDate(Date creationDate) { - this.creationDate = creationDate; - } - - public Date getExpirationDate() { - return expirationDate; - } - - public void setExpirationDate(Date expirationDate) { - this.expirationDate = expirationDate; - } - - public String getData() { - return data; - } - - public void setData(String data) { - this.data = data; - } - - public boolean isDeletable() { - return deletable; - } - - public void setDeletable(boolean deletable) { - this.deletable = deletable; - } - - @Override - public String toString() { - return "NativePersistenceCacheEntity{" + - "dn='" + dn + '\'' + - ", id='" + id + '\'' + - ", creationDate=" + creationDate + - ", expirationDate=" + expirationDate + - ", deletable=" + deletable + - ", data='" + data + '\'' + - '}'; - } -} diff --git a/oxService/src/main/java/org/gluu/service/cache/RedisConfiguration.java b/oxService/src/main/java/org/gluu/service/cache/RedisConfiguration.java deleted file mode 100644 index a70aa9c36..000000000 --- a/oxService/src/main/java/org/gluu/service/cache/RedisConfiguration.java +++ /dev/null @@ -1,96 +0,0 @@ -package org.gluu.service.cache; - - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -import java.io.Serializable; - -/** - * @author yuriyz on 02/23/2017. - */ -@JsonIgnoreProperties(ignoreUnknown = true) -public class RedisConfiguration implements Serializable { - - private static final long serialVersionUID = 5513197227832695471L; - - private RedisProviderType redisProviderType = RedisProviderType.STANDALONE; - - private String servers = "localhost:6379"; // server1:11211 server2:11211 - - private int defaultPutExpiration = 60; // in seconds - - private String password; - - private String decryptedPassword; - - private Boolean useSSL = false; - - private String sslTrustStoreFilePath = ""; - - public String getServers() { - return servers; - } - - public void setServers(String servers) { - this.servers = servers; - } - - public int getDefaultPutExpiration() { - return defaultPutExpiration; - } - - public void setDefaultPutExpiration(int defaultPutExpiration) { - this.defaultPutExpiration = defaultPutExpiration; - } - - public RedisProviderType getRedisProviderType() { - return redisProviderType; - } - - public void setRedisProviderType(RedisProviderType redisProviderType) { - this.redisProviderType = redisProviderType; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public Boolean getUseSSL() { - return useSSL != null ? useSSL : false; - } - - public void setUseSSL(Boolean useSSL) { - this.useSSL = useSSL; - } - - public String getSslTrustStoreFilePath() { - return sslTrustStoreFilePath; - } - - public void setSslTrustStoreFilePath(String sslTrustStoreFilePath) { - this.sslTrustStoreFilePath = sslTrustStoreFilePath; - } - - public String getDecryptedPassword() { - return decryptedPassword; - } - - public void setDecryptedPassword(String decryptedPassword) { - this.decryptedPassword = decryptedPassword; - } - - @Override - public String toString() { - return "RedisConfiguration{" + - "servers='" + servers + '\'' + - ", defaultPutExpiration=" + defaultPutExpiration + - ", redisProviderType=" + redisProviderType + - ", useSSL=" + useSSL + - ", sslTrustStoreFilePath=" + sslTrustStoreFilePath + - '}'; - } -} diff --git a/oxService/src/main/java/org/gluu/service/cache/RedisProviderFactory.java b/oxService/src/main/java/org/gluu/service/cache/RedisProviderFactory.java deleted file mode 100644 index 92b6eaff8..000000000 --- a/oxService/src/main/java/org/gluu/service/cache/RedisProviderFactory.java +++ /dev/null @@ -1,85 +0,0 @@ -package org.gluu.service.cache; - -import org.apache.commons.io.IOUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocketFactory; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; -import java.security.KeyStore; -import java.security.SecureRandom; - -/** - * Important : keep it weld free. It's reused by oxd ! - * - * @author yuriyz - */ -public final class RedisProviderFactory { - - private static final Logger LOG = LoggerFactory.getLogger(RedisProviderFactory.class); - - private RedisProviderFactory() { - } - - public static AbstractRedisProvider create(RedisConfiguration redisConfiguration) { - try { - LOG.debug("Creating RedisProvider ... configuration:" + redisConfiguration); - - switch (redisConfiguration.getRedisProviderType()) { - case STANDALONE: - return new RedisStandaloneProvider(redisConfiguration); - case CLUSTER: - return new RedisClusterProvider(redisConfiguration); - case SHARDED: - return new RedisShardedProvider(redisConfiguration); - default: - LOG.error("Failed to create RedisProvider. RedisProviderType is not supported by current version of oxcore: " - + redisConfiguration.getRedisProviderType() + ", redisConfiguration:" + redisConfiguration); - throw new RuntimeException( - "RedisProviderType is not supported by current version of oxcore: " + redisConfiguration.getRedisProviderType()); - } - } catch (Exception e) { - LOG.error("Failed to create RedisProvider."); - throw new RuntimeException("Error creating RedisProvider", e); - } - } - - public static void destroy(AbstractRedisProvider provider) { - if (provider != null) { - provider.destroy(); - } - } - - public static void destroySilently(AbstractRedisProvider provider) { - try { - destroy(provider); - } catch (Exception e) { - LOG.error("Failed to destroy redis provider.", e); - } - } - - public static SSLSocketFactory createTrustStoreSslSocketFactory(File keystoreFile) throws Exception { - - KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); - InputStream inputStream = null; - try { - inputStream = new FileInputStream(keystoreFile); - trustStore.load(inputStream, null); - } finally { - IOUtils.closeQuietly(inputStream); - } - - TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - trustManagerFactory.init(trustStore); - TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); - - SSLContext sslContext = SSLContext.getInstance("TLS"); - sslContext.init(null, trustManagers, new SecureRandom()); - return sslContext.getSocketFactory(); - } -} diff --git a/oxService/src/main/java/org/gluu/service/cdi/event/AppConfigurationReloadEvent.java b/oxService/src/main/java/org/gluu/service/cdi/event/AppConfigurationReloadEvent.java new file mode 100644 index 000000000..3bd2cb150 --- /dev/null +++ b/oxService/src/main/java/org/gluu/service/cdi/event/AppConfigurationReloadEvent.java @@ -0,0 +1,7 @@ +package org.gluu.service.cdi.event; + +/** + * @author Yuriy Movchan Date: 05/25/2020 + */ +public class AppConfigurationReloadEvent { +} diff --git a/oxService/src/main/java/org/gluu/service/cdi/event/ApplicationInitializedEvent.java b/oxService/src/main/java/org/gluu/service/cdi/event/ApplicationInitializedEvent.java new file mode 100644 index 000000000..18bc2b0e1 --- /dev/null +++ b/oxService/src/main/java/org/gluu/service/cdi/event/ApplicationInitializedEvent.java @@ -0,0 +1,8 @@ +package org.gluu.service.cdi.event; + +/** + * @author Yuriy Movchan Date: 11/27/2018 + */ +public class ApplicationInitializedEvent { + +} diff --git a/oxService/src/main/java/org/gluu/service/cdi/event/CibaRequestsProcessorEvent.java b/oxService/src/main/java/org/gluu/service/cdi/event/CibaRequestsProcessorEvent.java new file mode 100644 index 000000000..99f0216be --- /dev/null +++ b/oxService/src/main/java/org/gluu/service/cdi/event/CibaRequestsProcessorEvent.java @@ -0,0 +1,7 @@ +package org.gluu.service.cdi.event; + +/** + * @author Milton BO Date: 20/05/2020 + */ +public class CibaRequestsProcessorEvent { +} diff --git a/oxService/src/main/java/org/gluu/service/custom/CustomScriptService.java b/oxService/src/main/java/org/gluu/service/custom/CustomScriptService.java new file mode 100644 index 000000000..405181c91 --- /dev/null +++ b/oxService/src/main/java/org/gluu/service/custom/CustomScriptService.java @@ -0,0 +1,26 @@ +package org.gluu.service.custom; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; + +import org.gluu.service.OrganizationService; +import org.gluu.service.custom.script.AbstractCustomScriptService; + +/** + * Operations with custom scripts + * + * @author Yuriy Movchan Date: 09/07/2020 + */ +@ApplicationScoped +public class CustomScriptService extends AbstractCustomScriptService { + + private static final long serialVersionUID = -7670016078535552193L; + + @Inject + private OrganizationService organizationService; + + public String baseDn() { + return String.format("ou=scripts,%s", organizationService.getDnForOrganization(null)); + } + +} diff --git a/oxService/src/main/java/org/gluu/service/custom/script/AbstractCustomScriptService.java b/oxService/src/main/java/org/gluu/service/custom/script/AbstractCustomScriptService.java deleted file mode 100644 index 335a600b8..000000000 --- a/oxService/src/main/java/org/gluu/service/custom/script/AbstractCustomScriptService.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */package org.gluu.service.custom.script; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -import javax.inject.Inject; - -import org.gluu.model.custom.script.CustomScriptType; -import org.gluu.model.custom.script.model.CustomScript; -import org.gluu.persist.PersistenceEntryManager; -import org.gluu.search.filter.Filter; -import com.google.common.base.Optional; -import org.slf4j.Logger; - -/** - * Operations with custom scripts - * - * @author Yuriy Movchan Date: 12/03/2014 - */ -public abstract class AbstractCustomScriptService implements Serializable { - - private static final long serialVersionUID = -6187179012715072064L; - - @Inject - private Logger log; - - @Inject - private PersistenceEntryManager ldapEntryManager; - - public void add(CustomScript customScript) { - ldapEntryManager.persist(customScript); - } - - public void update(CustomScript customScript) { - ldapEntryManager.merge(customScript); - } - - public void remove(CustomScript customScript) { - ldapEntryManager.remove(customScript); - } - - public CustomScript getCustomScriptByDn(String customScriptDn, String... returnAttributes) { - return ldapEntryManager.find(customScriptDn, CustomScript.class, returnAttributes); - } - - public CustomScript getCustomScriptByDn(Class customScriptType, String customScriptDn) { - return (CustomScript) ldapEntryManager.find(customScriptType, customScriptDn); - } - - public Optional getCustomScriptByINum(String baseDn, String inum, String... returnAttributes) { - - final List customScriptTypeFilters = new ArrayList(); - - final Filter customScriptTypeFilter = Filter.createEqualityFilter("inum", inum); - customScriptTypeFilters.add(customScriptTypeFilter); - - final Filter filter = Filter.createORFilter(customScriptTypeFilters); - - final List result = ldapEntryManager.findEntries(baseDn, CustomScript.class, filter, returnAttributes); - - if (result.isEmpty()) { - - return Optional.absent(); - } - - return Optional.of(result.get(0)); - } - - - public List findAllCustomScripts(String[] returnAttributes) { - String baseDn = baseDn(); - - List result = ldapEntryManager.findEntries(baseDn, CustomScript.class, null, returnAttributes); - - return result; - } - - public List findCustomScripts(List customScriptTypes, String... returnAttributes) { - String baseDn = baseDn(); - - if ((customScriptTypes == null) || (customScriptTypes.size() == 0)) { - return findAllCustomScripts(returnAttributes); - } - - List customScriptTypeFilters = new ArrayList(); - for (CustomScriptType customScriptType : customScriptTypes) { - Filter customScriptTypeFilter = Filter.createEqualityFilter("oxScriptType", customScriptType.getValue()); - customScriptTypeFilters.add(customScriptTypeFilter); - } - - Filter filter = Filter.createORFilter(customScriptTypeFilters); - - List result = ldapEntryManager.findEntries(baseDn, CustomScript.class, filter, returnAttributes); - - return result; - } - - public String buildDn(String customScriptId) { - final StringBuilder dn = new StringBuilder(); - dn.append(String.format("inum=%s,", customScriptId)); - dn.append(baseDn()); - return dn.toString(); - } - - public abstract String baseDn(); - -} diff --git a/oxService/src/main/java/org/gluu/service/external/ExternalPersistenceExtensionService.java b/oxService/src/main/java/org/gluu/service/external/ExternalPersistenceExtensionService.java new file mode 100644 index 000000000..184f0140a --- /dev/null +++ b/oxService/src/main/java/org/gluu/service/external/ExternalPersistenceExtensionService.java @@ -0,0 +1,124 @@ +/* + * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Gluu + */ + +package org.gluu.service.external; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Instance; +import javax.inject.Inject; + +import org.gluu.model.SimpleCustomProperty; +import org.gluu.model.custom.script.CustomScriptType; +import org.gluu.model.custom.script.conf.CustomScriptConfiguration; +import org.gluu.model.custom.script.type.persistence.PersistenceType; +import org.gluu.persist.PersistenceEntryManager; +import org.gluu.persist.extension.PersistenceExtension; +import org.gluu.service.custom.script.ExternalScriptService; +import org.gluu.service.external.context.PersistenceExternalContext; + +/** + * Provides factory methods needed to create persistence extension + * + * @author Yuriy Movchan Date: 06/04/2020 + */ +@ApplicationScoped +public class ExternalPersistenceExtensionService extends ExternalScriptService { + + private static final long serialVersionUID = 5466361778036208685L; + + @Inject + private Instance persistenceEntryManagerInstance; + + @Inject + private Instance> persistenceEntryManagerListInstance; + + public ExternalPersistenceExtensionService() { + super(CustomScriptType.PERSISTENCE_EXTENSION); + } + + @Override + protected void reloadExternal() { + for (Iterator it = persistenceEntryManagerInstance.iterator(); it.hasNext();) { + PersistenceEntryManager persistenceEntryManager = it.next(); + executePersistenceExtensionAfterCreate(null, persistenceEntryManager); + } + + for (Iterator> it = persistenceEntryManagerListInstance.iterator(); it.hasNext();) { + List persistenceEntryManagerList = it.next(); + for (PersistenceEntryManager persistenceEntryManager : persistenceEntryManagerList) { + executePersistenceExtensionAfterCreate(null, persistenceEntryManager); + } + } + } + + public void executePersistenceExtensionAfterCreate(Properties connectionProperties, PersistenceEntryManager persistenceEntryManager) { + if (isEnabled()) { + PersistenceExternalContext persistenceExternalContext = new PersistenceExternalContext(); + persistenceExternalContext.setConnectionProperties(connectionProperties); + persistenceExternalContext.setPersistenceEntryManager(persistenceEntryManager); + + executeExternalOnAfterCreateMethod(persistenceExternalContext); + } + + setPersistenceExtension(persistenceEntryManager); + } + + public void executePersistenceExtensionAfterDestroy(PersistenceEntryManager persistenceEntryManager) { + if (isEnabled()) { + PersistenceExternalContext persistenceExternalContext = new PersistenceExternalContext(); + persistenceExternalContext.setPersistenceEntryManager(persistenceEntryManager); + + executeExternalOnAfterDestroyMethod(persistenceExternalContext); + } + } + + public void setPersistenceExtension(PersistenceEntryManager persistenceEntryManager) { + PersistenceExtension persistenceExtension = null; + if (isEnabled()) { + persistenceExtension = (PersistenceExtension) this.defaultExternalCustomScript.getExternalType(); + } + + persistenceEntryManager.setPersistenceExtension(persistenceExtension); + } + + public void executeExternalOnAfterCreateMethod(PersistenceExternalContext context) { + executeExternalOnAfterCreateMethod(this.defaultExternalCustomScript, context); + } + + public void executeExternalOnAfterCreateMethod(CustomScriptConfiguration customScriptConfiguration, PersistenceExternalContext context) { + try { + log.debug("Executing python 'onAfterCreate' method"); + PersistenceType persistenceType = (PersistenceType) customScriptConfiguration.getExternalType(); + Map configurationAttributes = customScriptConfiguration.getConfigurationAttributes(); + persistenceType.onAfterCreate(context, configurationAttributes); + } catch (Exception ex) { + log.error(ex.getMessage(), ex); + saveScriptError(customScriptConfiguration.getCustomScript(), ex); + } + } + + public void executeExternalOnAfterDestroyMethod(PersistenceExternalContext context) { + executeExternalOnAfterDestroyMethod(this.defaultExternalCustomScript, context); + } + + public void executeExternalOnAfterDestroyMethod(CustomScriptConfiguration customScriptConfiguration, PersistenceExternalContext context) { + try { + log.debug("Executing python 'onAfterDestroy' method"); + PersistenceType persistenceType = (PersistenceType) customScriptConfiguration.getExternalType(); + Map configurationAttributes = customScriptConfiguration.getConfigurationAttributes(); + persistenceType.onAfterDestroy(context, configurationAttributes); + } catch (Exception ex) { + log.error(ex.getMessage(), ex); + saveScriptError(customScriptConfiguration.getCustomScript(), ex); + } + } + +} diff --git a/oxService/src/main/java/org/gluu/service/external/context/ExternalScriptContext.java b/oxService/src/main/java/org/gluu/service/external/context/ExternalScriptContext.java new file mode 100644 index 000000000..4cdcf6eb6 --- /dev/null +++ b/oxService/src/main/java/org/gluu/service/external/context/ExternalScriptContext.java @@ -0,0 +1,73 @@ +/* + * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2014, Gluu + */ + +package org.gluu.service.external.context; + +import java.util.HashMap; +import java.util.Map; + +import javax.faces.context.ExternalContext; +import javax.faces.context.FacesContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Holds object required in custom scripts + * + * @author Yuriy Movchan Date: 07/01/2015 + */ + +public class ExternalScriptContext { + + private static final Logger log = LoggerFactory.getLogger(ExternalScriptContext.class); + + private final Map contextVariables = new HashMap<>(); + + protected HttpServletRequest httpRequest; + protected final HttpServletResponse httpResponse; + + public ExternalScriptContext(HttpServletRequest httpRequest) { + this(httpRequest, null); + } + + public ExternalScriptContext(HttpServletRequest httpRequest, HttpServletResponse httpResponse) { + this.httpRequest = httpRequest; + this.httpResponse = httpResponse; + + if (this.httpRequest == null) { + FacesContext facesContext = FacesContext.getCurrentInstance(); + if (facesContext != null) { + ExternalContext extCtx = facesContext.getExternalContext(); + if (extCtx != null) { + this.httpRequest = (HttpServletRequest) extCtx.getRequest(); + } + } + } + } + + public Logger getLog() { + return log; + } + + public HttpServletRequest getHttpRequest() { + return httpRequest; + } + + public HttpServletResponse getHttpResponse() { + return httpResponse; + } + + public String getIpAddress() { + return httpRequest != null ? httpRequest.getRemoteAddr() : ""; + } + + public Map getContextVariables() { + return contextVariables; + } +} diff --git a/oxService/src/main/java/org/gluu/service/external/context/PersistenceExternalContext.java b/oxService/src/main/java/org/gluu/service/external/context/PersistenceExternalContext.java new file mode 100644 index 000000000..7daabaa11 --- /dev/null +++ b/oxService/src/main/java/org/gluu/service/external/context/PersistenceExternalContext.java @@ -0,0 +1,43 @@ +/* + * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Gluu + */ + +package org.gluu.service.external.context; + +import java.util.Properties; + +import org.gluu.persist.PersistenceEntryManager; + +/** + * Holds object required in persistence scope custom scripts + * + * @author Yuriy Movchan Date: 06/05/2020 + */ +public class PersistenceExternalContext extends ExternalScriptContext { + + private Properties connectionProperties; + private PersistenceEntryManager persistenceEntryManager; + + public PersistenceExternalContext() { + super(null, null); + } + + public Properties getConnectionProperties() { + return connectionProperties; + } + + public void setConnectionProperties(Properties connectionProperties) { + this.connectionProperties = connectionProperties; + } + + public PersistenceEntryManager getPersistenceEntryManager() { + return persistenceEntryManager; + } + + public void setPersistenceEntryManager(PersistenceEntryManager persistenceEntryManager) { + this.persistenceEntryManager = persistenceEntryManager; + } + +} diff --git a/oxService/src/main/java/org/gluu/service/logger/LoggerService.java b/oxService/src/main/java/org/gluu/service/logger/LoggerService.java index 3c43ca3ae..b02d04bec 100644 --- a/oxService/src/main/java/org/gluu/service/logger/LoggerService.java +++ b/oxService/src/main/java/org/gluu/service/logger/LoggerService.java @@ -1,204 +1,311 @@ -package org.gluu.service.logger; - -import java.io.File; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.logging.LogManager; - -import javax.annotation.PostConstruct; -import javax.enterprise.event.Event; -import javax.enterprise.event.Observes; -import javax.inject.Inject; - -import org.apache.commons.lang.StringUtils; -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.core.LoggerContext; -import org.gluu.service.cdi.async.Asynchronous; -import org.gluu.service.cdi.event.ConfigurationUpdate; -import org.gluu.service.cdi.event.LoggerUpdateEvent; -import org.gluu.service.cdi.event.Scheduled; -import org.gluu.service.timer.event.TimerEvent; -import org.gluu.service.timer.schedule.TimerSchedule; -import org.gluu.util.StringHelper; -import org.slf4j.Logger; - -/** - * Logger service - * - * @author Yuriy Movchan Date: 08/19/2018 - */ -public abstract class LoggerService { - - private final static int DEFAULT_INTERVAL = 15; // 15 seconds - - @Inject - private Logger log; - - @Inject - private Event timerEvent; - - private AtomicBoolean isActive; - - @PostConstruct - public void create() { - this.isActive = new AtomicBoolean(false); - } - - public void initTimer() { - log.info("Initializing Logger Update Timer"); - - final int delay = 15; - final int interval = DEFAULT_INTERVAL; - - timerEvent.fire(new TimerEvent(new TimerSchedule(delay, interval), new LoggerUpdateEvent(), - Scheduled.Literal.INSTANCE)); - } - - @Asynchronous - public void updateLoggerTimerEvent(@Observes @Scheduled LoggerUpdateEvent loggerUpdateEvent) { - if (this.isActive.get()) { - return; - } - - if (!this.isActive.compareAndSet(false, true)) { - return; - } - - try { - updateLoggerConfiguration(); - } catch (Throwable ex) { - log.error("Exception happened while updating newly added logger configuration", ex); - } finally { - this.isActive.set(false); - } - } - - private void updateLoggerConfiguration() { - String loggingLevel = getLoggingLevel(); - if (StringHelper.isEmpty(loggingLevel)) { - return; - } - - Level level = Level.toLevel(loggingLevel, Level.INFO); - if (StringHelper.equalsIgnoreCase("DEFAULT", loggingLevel)) { - return; - } - - updateLoggers(level); - } - - public void updateLoggerSeverity(@Observes @ConfigurationUpdate Object appConfiguration) { - if (this.isActive.get()) { - return; - } - - if (!this.isActive.compareAndSet(false, true)) { - return; - } - - try { - updateLoggerSeverityImpl(); - } catch (Throwable ex) { - log.error("Exception happened while updating logger configuration after base configuration update", ex); - } finally { - this.isActive.set(false); - } - } - - public void updateLoggerSeverity() { - updateLoggerSeverityImpl(); - } - - private void updateLoggerSeverityImpl() { - if (isDisableJdkLogger()) { - disableJdkLogger(); - } - updateLoggerConfigLocation(); - - String loggingLevel = getLoggingLevel(); - if (StringHelper.isEmpty(loggingLevel)) { - return; - } - - log.info("Setting loggers level to: '{}'", loggingLevel); - if (StringHelper.equalsIgnoreCase("DEFAULT", loggingLevel)) { - log.info("Reloading log4j configuration"); - LoggerContext loggerContext = LoggerContext.getContext(false); - loggerContext.reconfigure(); - return; - } - - Level level = Level.toLevel(loggingLevel, Level.INFO); - updateLoggers(level); - } - - private void updateLoggers(Level level) { - LoggerContext loggerContext = LoggerContext.getContext(false); - - int count = 0; - for (org.apache.logging.log4j.core.Logger logger : loggerContext.getLoggers()) { - String loggerName = logger.getName(); - if (loggerName.startsWith("org.gluu")) { - if (logger.getLevel() != level) { - count++; - logger.setLevel(level); - } - } - } - - if (count > 0) { - log.info("Uppdated log level of '{}' loggers to {}", count, level.toString()); - } - } - - /** - * First trying to set external logger config from GluuAppliance. - * If there is no valid external path to log4j2.xml location then set default configuration. - */ - public void updateLoggerConfigLocation() { - if (setExternalLoggerConfig()) { - return; - } - - LoggerContext loggerContext = LoggerContext.getContext(false); - if (loggerContext.getConfigLocation() != null) { - loggerContext.setConfigLocation(null); - loggerContext.reconfigure(); - } - } - - private void disableJdkLogger() { - LogManager.getLogManager().reset(); - java.util.logging.Logger globalLogger = java.util.logging.Logger.getLogger(java.util.logging.Logger.GLOBAL_LOGGER_NAME); - if (globalLogger != null) { - globalLogger.setLevel(java.util.logging.Level.OFF); - } - } - - private boolean setExternalLoggerConfig() { - String externalLoggerConfiguration = getExternalLoggerConfiguration(); - log.info("External log configuration: {}", externalLoggerConfiguration); - if (StringUtils.isEmpty(externalLoggerConfiguration)) { - return false; - } - - File log4jFile = new File(externalLoggerConfiguration); - if (!log4jFile.exists()) { - log.info("External log configuration does not exist."); - return false; - } - - LoggerContext loggerContext = LoggerContext.getContext(false); - loggerContext.setConfigLocation(log4jFile.toURI()); - loggerContext.reconfigure(); - - return true; - } - - public abstract boolean isDisableJdkLogger(); - - public abstract String getLoggingLevel(); - - public abstract String getExternalLoggerConfiguration(); - - -} +package org.gluu.service.logger; + +import java.io.File; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.logging.LogManager; + +import javax.annotation.PostConstruct; +import javax.enterprise.event.Event; +import javax.enterprise.event.Observes; +import javax.inject.Inject; + +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.core.LoggerContext; +import org.gluu.model.types.LoggingLayoutType; +import org.gluu.service.cdi.async.Asynchronous; +import org.gluu.service.cdi.event.ConfigurationUpdate; +import org.gluu.service.cdi.event.LoggerUpdateEvent; +import org.gluu.service.cdi.event.Scheduled; +import org.gluu.service.timer.event.TimerEvent; +import org.gluu.service.timer.schedule.TimerSchedule; +import org.gluu.util.StringHelper; +import org.slf4j.Logger; + +/** + * Logger service + * + * @author Yuriy Movchan Date: 08/19/2018 + */ +public abstract class LoggerService { + + private final static int DEFAULT_INTERVAL = 15; // 15 seconds + + @Inject + private Logger log; + + @Inject + private Event timerEvent; + + private Level prevLogLevel; + + private AtomicBoolean isActive; + + @PostConstruct + public void create() { + this.isActive = new AtomicBoolean(false); + } + + public void initTimer() { + initTimer(false); + } + + public void initTimer(boolean updateNow) { + log.info("Initializing Logger Update Timer"); + + final int delay = 15; + final int interval = DEFAULT_INTERVAL; + + this.prevLogLevel = getCurrentLogLevel(); + + timerEvent.fire(new TimerEvent(new TimerSchedule(delay, interval), new LoggerUpdateEvent(), + Scheduled.Literal.INSTANCE)); + + if (updateNow) { + updateLoggerTimerEvent(null); + } + } + + + @Asynchronous + public void updateLoggerTimerEvent(@Observes @Scheduled LoggerUpdateEvent loggerUpdateEvent) { + if (this.isActive.get()) { + return; + } + + if (!this.isActive.compareAndSet(false, true)) { + return; + } + + try { + updateLoggerConfiguration(); + this.prevLogLevel = getCurrentLogLevel(); + } catch (Throwable ex) { + log.error("Exception happened while updating newly added logger configuration", ex); + } finally { + this.isActive.set(false); + } + } + + private void updateLoggerConfiguration() { + // Do periodic update to apply changes to new loggers as well + String loggingLevel = getLoggingLevel(); + if (StringHelper.isEmpty(loggingLevel) || StringUtils.isEmpty(this.getLoggingLayout()) + || StringHelper.equalsIgnoreCase("DEFAULT", loggingLevel)) { + return; + } + + Level level = Level.toLevel(loggingLevel, Level.INFO); + LoggingLayoutType loggingLayout = LoggingLayoutType.getByValue(this.getLoggingLayout().toUpperCase()); + + updateAppendersAndLogLevel(loggingLayout, prevLogLevel, level); + } + + public void updateLoggerSeverity(@Observes @ConfigurationUpdate Object appConfiguration) { + if (this.isActive.get()) { + return; + } + + if (!this.isActive.compareAndSet(false, true)) { + return; + } + + try { + updateLoggerSeverityImpl(); + } catch (Throwable ex) { + log.error("Exception happened while updating logger configuration after base configuration update", ex); + } finally { + this.isActive.set(false); + } + } + + public void updateLoggerSeverity() { + // Full log4j2 configuration reload + updateLoggerSeverityImpl(); + } + + private void updateLoggerSeverityImpl() { + setDisableJdkLogger(); + + if (setExternalLoggerConfig()) { + return; + } + + resetLoggerConfigLocation(); + + String loggingLevel = getLoggingLevel(); + if (StringHelper.isEmpty(loggingLevel) || StringUtils.isEmpty(this.getLoggingLayout()) + || StringHelper.equalsIgnoreCase("DEFAULT", loggingLevel)) { + return; + } + + Level level = Level.toLevel(loggingLevel, Level.INFO); + LoggingLayoutType loggingLayout = LoggingLayoutType.getByValue(this.getLoggingLayout().toUpperCase()); + + log.info("Setting layout and loggers level to '{}`, `{}' after configuration update", loggingLayout, loggingLevel); + + updateAppendersAndLogLevel(loggingLayout, prevLogLevel, level); + } + + private void setDisableJdkLogger() { + if (isDisableJdkLogger()) { + LogManager.getLogManager().reset(); + java.util.logging.Logger globalLogger = java.util.logging.Logger.getLogger(java.util.logging.Logger.GLOBAL_LOGGER_NAME); + if (globalLogger != null) { + globalLogger.setLevel(java.util.logging.Level.OFF); + } + } + } + + private boolean setExternalLoggerConfig() { + String externalLoggerConfiguration = getExternalLoggerConfiguration(); + log.info("External log configuration: {}", externalLoggerConfiguration); + if (StringUtils.isEmpty(externalLoggerConfiguration)) { + return false; + } + + File log4jFile = new File(externalLoggerConfiguration); + if (!log4jFile.exists()) { + log.info("External log configuration does not exist."); + return false; + } + + LoggerContext loggerContext = LoggerContext.getContext(false); + loggerContext.setConfigLocation(log4jFile.toURI()); + loggerContext.reconfigure(); + + return true; + } + + public void resetLoggerConfigLocation() { + log.info("Reloading log4j2 configuration"); + + LoggerContext loggerContext = LoggerContext.getContext(false); + if (loggerContext.getConfigLocation() != null) { + loggerContext.setConfigLocation(null); + } + loggerContext.reconfigure(); + } + + private void updateAppendersAndLogLevel(LoggingLayoutType loggingLayout, Level prevLevel, Level newLevel) { + if (loggingLayout == LoggingLayoutType.TEXT) { + if (newLevel != prevLevel) { + final LoggerContext ctx = LoggerContext.getContext(false); + ctx.getConfiguration().getRootLogger().setLevel(newLevel); + ctx.reconfigure(); + } + + LoggerContext loggerContext = LoggerContext.getContext(false); + + int count = 0; + for (org.apache.logging.log4j.core.Logger logger : loggerContext.getLoggers()) { + String loggerName = logger.getName(); + if (loggerName.startsWith("org.gluu")) { + if (logger.getLevel() != newLevel) { + count++; + logger.setLevel(newLevel); + } + } + } + + if (count > 0) { + log.info("Updated log level of '{}' loggers to {}", count, newLevel.toString()); + } + } +// boolean runLoggersUpdate = false; +// int loggerConfigUpdates = 0; +// int appenderConfigUpdates = 0; +// LoggerContext ctx = LoggerContext.getContext(false); +// +// AbstractConfiguration config = (AbstractConfiguration) ctx.getConfiguration(); +// for (Entry loggerConfigEntry : config.getLoggers().entrySet()) { +// LoggerConfig loggerConfig = loggerConfigEntry.getValue(); +// log.trace("Updating log configuration '{}'", loggerConfig.getName()); +// +// if (!loggerConfig.getLevel().equals(level)) { +// loggerConfig.setLevel(level); +// log.trace("Updating log level in configuration '{}' to '{}'", loggerConfig.getName(), level); +// runLoggersUpdate = true; +// loggerConfigUpdates++; +// } +// +// for (Map.Entry appenderEntry : loggerConfig.getAppenders().entrySet()) { +// Appender appender = appenderEntry.getValue(); +// log.trace("Updating appender '{}'", appender.getName()); +// +// Layout layout = appender.getLayout(); +// if (loggingLayout == LoggingLayoutType.TEXT) { +// layout = PatternLayout.newBuilder().withPattern("%d %-5p [%t] [%C{6}] (%F:%L) - %m%n").build(); +// } else if (loggingLayout == LoggingLayoutType.JSON) { +// layout = JsonLayout.createDefaultLayout(); +// } +// +// if (appender instanceof RollingFileAppender) { +// RollingFileAppender rollingFile = (RollingFileAppender) appender; +// if (rollingFile.getLayout().getClass().isAssignableFrom(layout.getClass())) { +// continue; +// } +// RollingFileAppender newFileAppender = RollingFileAppender.newBuilder() +// .setLayout(layout) +// .withStrategy(rollingFile.getManager().getRolloverStrategy()) +// .withPolicy(rollingFile.getTriggeringPolicy()) +// .withFileName(rollingFile.getFileName()) +// .withFilePattern(rollingFile.getFilePattern()) +// .setName(rollingFile.getName()) +// .build(); +// newFileAppender.start(); +// appender.stop(); +// loggerConfig.removeAppender(appenderEntry.getKey()); +// loggerConfig.addAppender(newFileAppender, null, null); +// +// runLoggersUpdate = true; +// appenderConfigUpdates++; +// } else if (appender instanceof ConsoleAppender) { +// ConsoleAppender consoleAppender = (ConsoleAppender) appender; +// if (consoleAppender.getLayout().getClass().isAssignableFrom(layout.getClass())) { +// continue; +// } +// +// ConsoleAppender newConsoleAppender = ConsoleAppender.newBuilder() +// .setLayout(layout) +// .setTarget(consoleAppender.getTarget()) +// .setName(consoleAppender.getName()) +// .build(); +// newConsoleAppender.start(); +// appender.stop(); +// loggerConfig.removeAppender(appenderEntry.getKey()); +// loggerConfig.addAppender(newConsoleAppender, null, null); +// +// runLoggersUpdate = true; +// appenderConfigUpdates++; +// } +// } +// } +// +// if (runLoggersUpdate) { +// log.trace("Trigger loggers update after '{}' updates", loggerConfigUpdates + appenderConfigUpdates); +// ctx.updateLoggers(); +// } + } + + private Level getCurrentLogLevel() { + String loggingLevel = getLoggingLevel(); + if (StringHelper.isEmpty(loggingLevel) || StringUtils.isEmpty(this.getLoggingLayout()) + || StringHelper.equalsIgnoreCase("DEFAULT", loggingLevel)) { + return Level.INFO; + } + + Level level = Level.toLevel(loggingLevel, Level.INFO); + + return level; + } + + public abstract boolean isDisableJdkLogger(); + + public abstract String getLoggingLevel(); + + public abstract String getExternalLoggerConfiguration(); + + public abstract String getLoggingLayout(); + +} diff --git a/oxService/src/main/java/org/gluu/service/metric/LdapEntryReporter.java b/oxService/src/main/java/org/gluu/service/metric/LdapEntryReporter.java index 6cf0beb88..0cd9c40f3 100644 --- a/oxService/src/main/java/org/gluu/service/metric/LdapEntryReporter.java +++ b/oxService/src/main/java/org/gluu/service/metric/LdapEntryReporter.java @@ -226,19 +226,26 @@ private List builTimerEntries(SortedMap timers, Set< private void addMandatoryAttributes(MetricService metricService, Date startTime, Date endTime, List metricEntries, Date creationTime) { + String nodeIndetifier = metricService.getNodeIndetifier(); + ApplicationType applicationType = metricService.getApplicationType(); + for (MetricEntry metricEntry : metricEntries) { - String id = metricService.getuUiqueIdentifier(); - String dn = metricService.buildDn(id, creationTime, ApplicationType.OX_AUTH); + String id = metricService.getUiqueIdentifier(); + String dn = metricService.buildDn(id, creationTime, applicationType); metricEntry.setId(id); metricEntry.setDn(dn); - metricEntry.setApplicationType(ApplicationType.OX_AUTH); + metricEntry.setApplicationType(applicationType); + metricEntry.setNodeIndetifier(nodeIndetifier); metricEntry.setStartDate(startTime); metricEntry.setEndDate(endTime); metricEntry.setCreationDate(creationTime); metricEntry.setExpirationDate(DateUtils.addDays(creationTime, metricService.getEntryLifetimeInDays())); + + int ttl = (int) ((metricEntry.getExpirationDate().getTime() - creationTime.getTime()) / 1000L); + metricEntry.setTtl(ttl); } } diff --git a/oxService/src/main/java/org/gluu/service/metric/MetricService.java b/oxService/src/main/java/org/gluu/service/metric/MetricService.java index 47707e215..f93efc326 100644 --- a/oxService/src/main/java/org/gluu/service/metric/MetricService.java +++ b/oxService/src/main/java/org/gluu/service/metric/MetricService.java @@ -119,6 +119,10 @@ public void createBranch(String branchDn, String ou) { } public void prepareBranch(Date creationDate, ApplicationType applicationType) { + if (!getEntryManager().hasBranchesSupport(baseDn())) { + return; + } + String baseDn = buildDn(null, creationDate, applicationType); // Create ou=YYYY-MM branch if needed if (!containsBranch(baseDn)) { @@ -165,7 +169,7 @@ public void remove(MetricEntry metricEntry) { } public void removeBranch(String branchDn) { - getEntryManager().removeRecursively(branchDn); + getEntryManager().removeRecursively(branchDn, SimpleBranch.class); } public MetricEntry getMetricEntryByDn(MetricType metricType, String metricEventDn) { @@ -219,9 +223,15 @@ public Map> findMetricEntry(ApplicationT return result; } - public List getExpiredMetricEntries(DefaultBatchOperation batchOperation, String baseDnForPeriod, Date expirationDate, + public List getExpiredMetricEntries(DefaultBatchOperation batchOperation, ApplicationType applicationType, String baseDnForPeriod, Date expirationDate, int count, int chunkSize) { - Filter expiratioFilter = Filter.createLessOrEqualFilter("oxStartDate", getEntryManager().encodeTime(baseDnForPeriod, expirationDate)); + Filter expiratioStartDateFilter = Filter.createLessOrEqualFilter("oxStartDate", getEntryManager().encodeTime(baseDnForPeriod, expirationDate)); + Filter expiratioFilter = expiratioStartDateFilter; + + if (applicationType != null) { + Filter applicationTypeFilter = Filter.createEqualityFilter("oxMetricType", applicationType.getValue()); + expiratioFilter = Filter.createANDFilter(expiratioStartDateFilter, applicationTypeFilter); + } List metricEntries = getEntryManager().findEntries(baseDnForPeriod, MetricEntry.class, expiratioFilter, SearchScope.SUB, new String[] { "uniqueIdentifier" }, batchOperation, 0, count, chunkSize); @@ -240,7 +250,7 @@ public List findAllPeriodBranches(DefaultBatchOperation keepBaseDnForPeriod = getBaseDnForPeriod(applicationType, expirationDate, new Date()); // Remove expired entries @@ -258,33 +268,35 @@ public void performAction(List entries) { } } }; - getExpiredMetricEntries(metricEntryBatchOperation, baseDnForPeriod, expirationDate, count, chunkSize); + getExpiredMetricEntries(metricEntryBatchOperation, applicationType, baseDnForPeriod, expirationDate, count, chunkSize); } - DefaultBatchOperation batchOperation = new DefaultBatchOperation() { - @Override - public boolean collectSearchResult(int size) { - return false; - } - - @Override - public void performAction(List objects) { - String baseDn = buildDn(null, null, applicationType); - Set periodBranchesStrings = new HashSet(); - for (SimpleBranch periodBranch : objects) { - if (!StringHelper.equalsIgnoreCase(baseDn, periodBranch.getDn())) { - periodBranchesStrings.add(periodBranch.getDn()); - } - } - periodBranchesStrings.removeAll(keepBaseDnForPeriod); - - // Remove expired months - for (String baseDnForPeriod : periodBranchesStrings) { - removeBranch(baseDnForPeriod); - } - } - }; - findAllPeriodBranches(batchOperation, applicationType, count, chunkSize); + if (!getEntryManager().hasBranchesSupport(buildDn(null, null, applicationType))) { + DefaultBatchOperation batchOperation = new DefaultBatchOperation() { + @Override + public boolean collectSearchResult(int size) { + return false; + } + + @Override + public void performAction(List objects) { + String baseDn = buildDn(null, null, applicationType); + Set periodBranchesStrings = new HashSet(); + for (SimpleBranch periodBranch : objects) { + if (!StringHelper.equalsIgnoreCase(baseDn, periodBranch.getDn())) { + periodBranchesStrings.add(periodBranch.getDn()); + } + } + periodBranchesStrings.removeAll(keepBaseDnForPeriod); + + // Remove expired months + for (String baseDnForPeriod : periodBranchesStrings) { + removeBranch(baseDnForPeriod); + } + } + }; + findAllPeriodBranches(batchOperation, applicationType, count, chunkSize); + } } private Set getBaseDnForPeriod(ApplicationType applicationType, Date startDate, Date endDate) { @@ -327,7 +339,7 @@ private Set getBaseDnForPeriod(ApplicationType applicationType, Date sta return metricDns; } - public String getuUiqueIdentifier() { + public String getUiqueIdentifier() { return UUID.randomUUID().toString(); } @@ -386,5 +398,7 @@ public Set getRegisteredMetricTypes() { public abstract ApplicationType getApplicationType(); + public abstract String getNodeIndetifier(); + public abstract PersistenceEntryManager getEntryManager(); } diff --git a/oxService/src/main/java/org/gluu/service/net/NetworkService.java b/oxService/src/main/java/org/gluu/service/net/NetworkService.java index 563555ee6..c04be83c7 100644 --- a/oxService/src/main/java/org/gluu/service/net/NetworkService.java +++ b/oxService/src/main/java/org/gluu/service/net/NetworkService.java @@ -5,6 +5,7 @@ */ package org.gluu.service.net; +import org.gluu.net.InetAddressUtility; import org.gluu.util.StringHelper; import org.slf4j.Logger; @@ -65,4 +66,9 @@ public String getHost(String serverUri) { return serverUri; } + + public String getMacAdress() { + return InetAddressUtility.getMACAddressOrNull(); + } + } diff --git a/oxService/src/main/java/org/gluu/service/security/protect/AuthenticationProtectionService.java b/oxService/src/main/java/org/gluu/service/security/protect/AuthenticationProtectionService.java index c71809d5b..945a7c080 100644 --- a/oxService/src/main/java/org/gluu/service/security/protect/AuthenticationProtectionService.java +++ b/oxService/src/main/java/org/gluu/service/security/protect/AuthenticationProtectionService.java @@ -8,7 +8,6 @@ import org.gluu.model.security.protect.AuthenticationAttempt; import org.gluu.model.security.protect.AuthenticationAttemptList; import org.gluu.service.CacheService; -import org.python.jline.internal.Log; import org.slf4j.Logger; /** @@ -105,7 +104,7 @@ public void doDelayIfNeeded(String key) { log.debug("Current login attempt requires delay: '{}' seconds", delayTime); Thread.sleep(delayTime * 1000); } catch (InterruptedException ex) { - Log.error("Failed to process authentication delay"); + log.error("Failed to process authentication delay"); } } diff --git a/oxService/src/main/java/org/gluu/service/util/PageService.java b/oxService/src/main/java/org/gluu/service/util/PageService.java index 7bd135598..1e77bd8ac 100644 --- a/oxService/src/main/java/org/gluu/service/util/PageService.java +++ b/oxService/src/main/java/org/gluu/service/util/PageService.java @@ -14,9 +14,10 @@ * @author Yuriy Movchan */ @ApplicationScoped +@Named public class PageService { - - private static final DateFormat CURRENT_DATE_TIME_FORMATTER = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss a"); + + private final String CURRENT_DATE_TIME_FORMATTER = "yyyy-MM-dd hh:mm:ss a"; public String getRootUrlByRequest(HttpServletRequest request) { String url = request.getRequestURL().toString(); @@ -24,7 +25,8 @@ public String getRootUrlByRequest(HttpServletRequest request) { } public String getCurrentDateTime() { - return CURRENT_DATE_TIME_FORMATTER.format(new Date()); + DateFormat dateFormat = new SimpleDateFormat(CURRENT_DATE_TIME_FORMATTER); + return dateFormat.format(new Date()); } } diff --git a/oxService/src/main/java/org/gluu/util/OxConstants.java b/oxService/src/main/java/org/gluu/util/OxConstants.java deleted file mode 100644 index 56eb6cb86..000000000 --- a/oxService/src/main/java/org/gluu/util/OxConstants.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */package org.gluu.util; - -/** - * Constants loads the LDAP schema attribute names like uid, iname - * - * @author Yuriy Movchan - * @version 0.1, 10/14/2010 - */ -public class OxConstants { - - public static final String UID = "uid"; - public static final String OBJECT_CLASS = "objectClass"; - - public static final String INUM = "inum"; - public static final String INAME = "iname"; - public static final String DISPLAY_NAME = "displayName"; - public static final String DESCRIPTION = "description"; - public static final String ORIGIN = "gluuAttributeOrigin"; - public static final String MAIL = "mail"; - - public static final String CACHE_ORGANIZATION_KEY = "organization"; - public static final String CACHE_METRICS_KEY = "metrics"; - public static final String CACHE_APPLICATION_NAME = "ApplicationCache"; - public static final String CACHE_ATTRIBUTE_NAME = "AttributeCache"; - public static final String CACHE_LOOKUP_NAME = "LookupCache"; - public static final String CACHE_METRICS_NAME = "metricsCache"; - - public static final String CACHE_ATTRIBUTE_KEY_LIST = "attributeList"; - public static final String CACHE_ACTIVE_ATTRIBUTE_KEY_LIST = "activeAttributeList"; - public static final String CACHE_ACTIVE_ATTRIBUTE_NAME = "ActiveAttributeCache"; - - public static final String SCRIPT_TYPE_INTERNAL_RESERVED_NAME = "simple_password_auth"; - -} diff --git a/oxService/src/test/java/org/gluu/service/cache/CouchbaseNativeBenchmarkCacheTest.java b/oxService/src/test/java/org/gluu/service/cache/CouchbaseNativeBenchmarkCacheTest.java new file mode 100644 index 000000000..7a00f031e --- /dev/null +++ b/oxService/src/test/java/org/gluu/service/cache/CouchbaseNativeBenchmarkCacheTest.java @@ -0,0 +1,96 @@ +package org.gluu.service.cache; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; + +import java.io.IOException; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.UUID; + +import org.gluu.orm.couchbase.impl.CouchbaseEntryManager; +import org.gluu.orm.couchbase.impl.CouchbaseEntryManagerFactory; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** + * @author Yuriy Movchan Date: 11/29/2019 + */ +public class CouchbaseNativeBenchmarkCacheTest { + + private CouchbaseEntryManager entryManager; + + @BeforeClass + public void init() { + this.entryManager = createCouchbaseEntryManager(); + } + + @AfterClass + public void destroy() { + this.entryManager.destroy(); + } + + @Test(enabled = false, threadPoolSize = 300, invocationCount = 10000) // manual + public void couchbaseCacheProvider() throws IOException { + final String baseDn = "ou=cache,o=gluu"; + + final CacheConfiguration cacheConfiguration = new CacheConfiguration(); + cacheConfiguration.setNativePersistenceConfiguration(new NativePersistenceConfiguration()); + cacheConfiguration.getNativePersistenceConfiguration().setBaseDn(""); + + NativePersistenceCacheProvider provider = new NativePersistenceCacheProvider(); + provider.configure(cacheConfiguration, entryManager); + + provider.setBaseDn(baseDn); + + Map sessionAttributes = new HashMap<>(); + sessionAttributes.put("attr1", "value1"); + sessionAttributes.put("attr2", "value2"); + + SampleSessionId sessionId = new SampleSessionId(); + sessionId.setId(UUID.randomUUID().toString()); + sessionId.setDn(sessionId.getId()); + sessionId.setAuthenticationTime(new Date()); + sessionId.setState(SessionIdState.AUTHENTICATED); + sessionId.setSessionAttributes(sessionAttributes); + + provider.put(130, sessionId.getId(), sessionId); + + final SampleSessionId fromCache = (SampleSessionId) provider.get(sessionId.getId()); + + assertNotNull(fromCache, "Failed to get by key: " + sessionId.getId() + " Cache key: " + provider.hashKey(sessionId.getId())); + assertEquals(fromCache.getId(), sessionId.getId(), "Get session with invaid key: " + sessionId.getId()); + } + + // MODIFY ACCORDING TO YOUR SERVER + private Properties getSampleConnectionProperties() { + Properties connectionProperties = new Properties(); + + connectionProperties.put("couchbase.servers", "test.gluu.org"); + connectionProperties.put("couchbase.auth.userName", "admin"); + connectionProperties.put("couchbase.auth.userPassword", "test"); + connectionProperties.put("couchbase.buckets", "gluu, gluu_cache"); + + connectionProperties.put("couchbase.bucket.default", "gluu"); + connectionProperties.put("couchbase.bucket.gluu_cache.mapping", "cache"); + + connectionProperties.put("couchbase.password.encryption.method", "CRYPT-SHA-256"); + + return connectionProperties; + } + + private CouchbaseEntryManager createCouchbaseEntryManager() { + CouchbaseEntryManagerFactory couchbaseEntryManagerFactory = new CouchbaseEntryManagerFactory(); + couchbaseEntryManagerFactory.create(); + Properties connectionProperties = getSampleConnectionProperties(); + + CouchbaseEntryManager couchbaseEntryManager = couchbaseEntryManagerFactory.createEntryManager(connectionProperties); + System.out.println("Created CouchbaseEntryManager: " + couchbaseEntryManager); + + return couchbaseEntryManager; + } + +} diff --git a/oxService/src/test/java/org/gluu/service/cache/CouchbaseNativeCacheTest.java b/oxService/src/test/java/org/gluu/service/cache/CouchbaseNativeCacheTest.java index 6e4a17271..e3a40b2c0 100644 --- a/oxService/src/test/java/org/gluu/service/cache/CouchbaseNativeCacheTest.java +++ b/oxService/src/test/java/org/gluu/service/cache/CouchbaseNativeCacheTest.java @@ -1,7 +1,7 @@ package org.gluu.service.cache; -import org.gluu.persist.couchbase.impl.CouchbaseEntryManager; -import org.gluu.persist.couchbase.impl.CouchbaseEntryManagerFactory; +import org.gluu.orm.couchbase.impl.CouchbaseEntryManager; +import org.gluu.orm.couchbase.impl.CouchbaseEntryManagerFactory; import org.testng.annotations.Test; import java.io.IOException; @@ -27,9 +27,9 @@ public void couchbaseCacheProvider() throws IOException { cacheConfiguration.getNativePersistenceConfiguration().setBaseDn(""); NativePersistenceCacheProvider provider = new NativePersistenceCacheProvider(); + provider.configure(cacheConfiguration, manager); + provider.setBaseDn(baseDn); - provider.setCacheConfiguration(cacheConfiguration); - provider.setEntryManager(manager); Map sessionAttributes = new HashMap<>(); sessionAttributes.put("attr1", "value1"); diff --git a/oxService/src/test/java/org/gluu/service/cache/InMemoryCacheProviderTest.java b/oxService/src/test/java/org/gluu/service/cache/InMemoryCacheProviderTest.java index 797f976d5..88082641e 100644 --- a/oxService/src/test/java/org/gluu/service/cache/InMemoryCacheProviderTest.java +++ b/oxService/src/test/java/org/gluu/service/cache/InMemoryCacheProviderTest.java @@ -18,8 +18,9 @@ public class InMemoryCacheProviderTest { @BeforeClass public void beforeClass() { + CacheConfiguration cacheConfiguration = new CacheConfiguration(); cache = new InMemoryCacheProvider(); - cache.setCacheConfiguration(new CacheConfiguration()); + cache.configure(cacheConfiguration); cache.create(); } diff --git a/oxService/src/test/java/org/gluu/service/cache/SampleSessionId.java b/oxService/src/test/java/org/gluu/service/cache/SampleSessionId.java index 4cece445c..86863f6f9 100644 --- a/oxService/src/test/java/org/gluu/service/cache/SampleSessionId.java +++ b/oxService/src/test/java/org/gluu/service/cache/SampleSessionId.java @@ -1,6 +1,5 @@ package org.gluu.service.cache; -import com.couchbase.client.java.cluster.User; import com.google.common.collect.Maps; import org.gluu.persist.annotation.AttributeName; import org.gluu.persist.annotation.DN; @@ -64,9 +63,6 @@ public class SampleSessionId implements Serializable { @Transient private transient boolean persisted; - @Transient - private User user; - public SampleSessionId() { } @@ -149,14 +145,6 @@ public void setUserDn(String p_userDn) { userDn = p_userDn != null ? p_userDn : ""; } - public User getUser() { - return user; - } - - public void setUser(User user) { - this.user = user; - } - public Date getAuthenticationTime() { return authenticationTime; } diff --git a/oxUtil/pom.xml b/oxUtil/pom.xml index 5edda372d..b6cf2bba6 100644 --- a/oxUtil/pom.xml +++ b/oxUtil/pom.xml @@ -1,102 +1,105 @@ - - - 4.0.0 - oxcore-util - jar - oxUtil - - - org.gluu - oxcore - 4.0.0-SNAPSHOT - - - - - ${project.groupId} - oxcore-persistence-annotation - ${project.version} - - - - - javax.persistence - persistence-api - - - - - org.apache.logging.log4j - log4j-api - - - org.apache.logging.log4j - log4j-1.2-api - - - org.slf4j - slf4j-api - - - org.apache.logging.log4j - log4j-slf4j-impl - - - - commons-codec - commons-codec - - - commons-configuration - commons-configuration - - - org.apache.commons - commons-text - - - commons-io - commons-io - - - commons-httpclient - commons-httpclient - - - org.apache.commons - commons-exec - - - - org.apache.httpcomponents - httpcore - - - org.apache.httpcomponents - httpclient - - - - com.fasterxml.jackson.core - jackson-annotations - - - com.fasterxml.jackson.core - jackson-core - - - com.fasterxml.jackson.core - jackson-databind - - - org.jboss.resteasy - resteasy-jackson2-provider - - - javax.servlet - javax.servlet-api - - - + + + 4.0.0 + oxcore-util + jar + oxUtil + + + org.gluu + oxcore + 4.5.6-SNAPSHOT + + + + + org.gluu + gluu-orm-annotation + + + + + javax.persistence + persistence-api + + + + + org.apache.logging.log4j + log4j-api + + + org.apache.logging.log4j + log4j-core + + + org.apache.logging.log4j + log4j-1.2-api + + + org.slf4j + slf4j-api + + + org.apache.logging.log4j + log4j-slf4j-impl + + + + commons-codec + commons-codec + + + commons-configuration + commons-configuration + + + org.apache.commons + commons-text + + + commons-io + commons-io + + + org.apache.commons + commons-exec + + + + org.apache.httpcomponents + httpcore + + + org.apache.httpcomponents + httpclient + + + + com.fasterxml.jackson.core + jackson-annotations + + + com.fasterxml.jackson.core + jackson-core + + + com.fasterxml.jackson.core + jackson-databind + + + org.jboss.resteasy + resteasy-jackson2-provider + + + javax.servlet + javax.servlet-api + + + jakarta.xml.bind + jakarta.xml.bind-api + + + \ No newline at end of file diff --git a/oxUtil/src/main/java/org/gluu/model/ProgrammingLanguage.java b/oxUtil/src/main/java/org/gluu/model/ProgrammingLanguage.java index 6d559844e..ce042531e 100644 --- a/oxUtil/src/main/java/org/gluu/model/ProgrammingLanguage.java +++ b/oxUtil/src/main/java/org/gluu/model/ProgrammingLanguage.java @@ -18,7 +18,7 @@ */ public enum ProgrammingLanguage implements AttributeEnum { - PYTHON("python", "Python"), JAVA_SCRIPT("javascript", "JavaScript"); + PYTHON("python", "Jython"), JAVA_SCRIPT("javascript", "JavaScript"); private String value; private String displayName; diff --git a/oxUtil/src/main/java/org/gluu/model/SelectableEntity.java b/oxUtil/src/main/java/org/gluu/model/SelectableEntity.java index e65297a7d..75a606f94 100644 --- a/oxUtil/src/main/java/org/gluu/model/SelectableEntity.java +++ b/oxUtil/src/main/java/org/gluu/model/SelectableEntity.java @@ -45,4 +45,11 @@ public void setSelected(boolean selected) { this.selected = selected; } + @Override + public String toString() { + return "SelectableEntity{" + + "entity=" + entity + + ", selected=" + selected + + '}'; + } } diff --git a/oxUtil/src/main/java/org/gluu/model/SmtpConfiguration.java b/oxUtil/src/main/java/org/gluu/model/SmtpConfiguration.java index 0c3ea30ce..f5baf736f 100644 --- a/oxUtil/src/main/java/org/gluu/model/SmtpConfiguration.java +++ b/oxUtil/src/main/java/org/gluu/model/SmtpConfiguration.java @@ -27,8 +27,8 @@ public class SmtpConfiguration implements java.io.Serializable { @JsonProperty("port") private int port; - @JsonProperty("requires-ssl") - private boolean requiresSsl; + @JsonProperty("connect-protection") + private SmtpConnectProtectionType connectProtection; @JsonProperty("trust-host") private boolean serverTrust; @@ -52,6 +52,22 @@ public class SmtpConfiguration implements java.io.Serializable { @JsonIgnore private String passwordDecrypted; + @JsonProperty("key-store") + private String keyStore; + + @JsonProperty("key-store-password") + private String keyStorePassword; + + @Transient + @JsonIgnore + private String keyStorePasswordDecrypted; + + @JsonProperty("key-store-alias") + private String keyStoreAlias; + + @JsonProperty("signing-algorithm") + private String signingAlgorithm; + public String getHost() { return host; } @@ -68,12 +84,12 @@ public void setPort(int port) { this.port = port; } - public boolean isRequiresSsl() { - return requiresSsl; + public SmtpConnectProtectionType getConnectProtection() { + return connectProtection; } - public void setRequiresSsl(boolean requiresSsl) { - this.requiresSsl = requiresSsl; + public void setConnectProtection(SmtpConnectProtectionType connectProtection) { + this.connectProtection = connectProtection; } public boolean isServerTrust() { @@ -137,5 +153,48 @@ public String getPasswordDecrypted() { public void setPasswordDecrypted(String passwordDecrypted) { this.passwordDecrypted = passwordDecrypted; } + + public SmtpConnectProtectionType[] getConnectProtectionList() { + return SmtpConnectProtectionType.values(); + } + + public String getKeyStore() { + return keyStore; + } + + public void setKeyStore(String keyStore) { + this.keyStore = keyStore; + } + + public String getKeyStorePassword() { + return keyStorePassword; + } + public void setKeyStorePassword(String keyStorePassword) { + this.keyStorePassword = keyStorePassword; + } + + public String getKeyStorePasswordDecrypted() { + return keyStorePasswordDecrypted; + } + + public void setKeyStorePasswordDecrypted(String keyStorePasswordDecrypted) { + this.keyStorePasswordDecrypted = keyStorePasswordDecrypted; + } + + public String getKeyStoreAlias() { + return keyStoreAlias; + } + + public void setKeyStoreAlias(String keyStoreAlias) { + this.keyStoreAlias = keyStoreAlias; + } + + public String getSigningAlgorithm() { + return signingAlgorithm; + } + + public void setSigningAlgorithm(String signingAlgorithm) { + this.signingAlgorithm = signingAlgorithm; + } } diff --git a/oxUtil/src/main/java/org/gluu/model/SmtpConnectProtectionType.java b/oxUtil/src/main/java/org/gluu/model/SmtpConnectProtectionType.java new file mode 100644 index 000000000..ba68af7c6 --- /dev/null +++ b/oxUtil/src/main/java/org/gluu/model/SmtpConnectProtectionType.java @@ -0,0 +1,71 @@ +/** + * + */ +package org.gluu.model; + +import java.util.HashMap; +import java.util.Map; + +import org.gluu.persist.annotation.AttributeEnum; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * @author Sergey Manoylo + * @version 06/24/2022 + */ +public enum SmtpConnectProtectionType implements AttributeEnum { + + NONE("None", "NONE"), START_TLS("StartTls", "STARTTLS"), SSL_TLS("SslTls", "SSL/TLS"); + + private String value; + private String displayName; + + private static final Map mapByValues = new HashMap<>(); + + static { + for (SmtpConnectProtectionType enumType : values()) { + mapByValues.put(enumType.getValue(), enumType); + } + } + + /** + * + * @param value + * @param displayName + */ + private SmtpConnectProtectionType(String value, String displayName) { + this.value = value; + this.displayName = displayName; + } + + @JsonCreator + public static SmtpConnectProtectionType forValues(String value) { + return getByValue(value); + } + + @Override + public String getValue() { + return value; + } + + public String getDisplayName() { + return displayName; + } + + public static SmtpConnectProtectionType getByValue(String value) { + return mapByValues.get(value); + } + + @Override + public Enum resolveByValue(String value) { + return getByValue(value); + } + + @JsonValue + @Override + public String toString() { + return value; + } +} diff --git a/oxUtil/src/main/java/org/gluu/model/TrustContact.java b/oxUtil/src/main/java/org/gluu/model/TrustContact.java index e4b33e630..790c588c6 100644 --- a/oxUtil/src/main/java/org/gluu/model/TrustContact.java +++ b/oxUtil/src/main/java/org/gluu/model/TrustContact.java @@ -6,9 +6,6 @@ package org.gluu.model; -import javax.xml.bind.annotation.XmlRootElement; - -@XmlRootElement public class TrustContact implements java.io.Serializable { private static final long serialVersionUID = -3268590744030750954L; diff --git a/oxUtil/src/main/java/org/gluu/model/ldap/GluuLdapConfiguration.java b/oxUtil/src/main/java/org/gluu/model/ldap/GluuLdapConfiguration.java index 39a2724a2..5f936a253 100644 --- a/oxUtil/src/main/java/org/gluu/model/ldap/GluuLdapConfiguration.java +++ b/oxUtil/src/main/java/org/gluu/model/ldap/GluuLdapConfiguration.java @@ -38,7 +38,7 @@ public class GluuLdapConfiguration implements Serializable { @JsonProperty("servers") private List serversStringsList; - private int maxConnections; + private int maxConnections = 2; private boolean useSSL; @JsonIgnore diff --git a/oxUtil/src/main/java/org/gluu/model/net/HttpServiceResponse.java b/oxUtil/src/main/java/org/gluu/model/net/HttpServiceResponse.java new file mode 100644 index 000000000..0d3803ec9 --- /dev/null +++ b/oxUtil/src/main/java/org/gluu/model/net/HttpServiceResponse.java @@ -0,0 +1,43 @@ +/** + * + */ +package org.gluu.model.net; + +import java.io.Serializable; + +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpRequestBase; + +/** + * @author Yuriy Movchan Date: 07/14/2015 + * + */ +public class HttpServiceResponse implements Serializable { + + private static final long serialVersionUID = 2218884738060554709L; + + private HttpRequestBase httpRequest; + private HttpResponse httpResponse; + + public HttpServiceResponse(HttpRequestBase httpRequest, HttpResponse httpResponse) { + this.httpRequest = httpRequest; + this.httpResponse = httpResponse; + } + + public HttpRequestBase getHttpRequest() { + return httpRequest; + } + + public HttpResponse getHttpResponse() { + return httpResponse; + } + + public void closeConnection() { + if (httpRequest == null) { + return; + } + + httpRequest.releaseConnection(); + } + +} diff --git a/oxUtil/src/main/java/org/gluu/net/HttpServiceUtility.java b/oxUtil/src/main/java/org/gluu/net/HttpServiceUtility.java new file mode 100644 index 000000000..e82607f82 --- /dev/null +++ b/oxUtil/src/main/java/org/gluu/net/HttpServiceUtility.java @@ -0,0 +1,320 @@ +/* + * oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2014, Gluu + */ + +package org.gluu.net; + +import java.io.File; +import java.io.IOException; +import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.Charset; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.util.Map; +import java.util.Map.Entry; + +import javax.net.ssl.SSLContext; +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.codec.binary.Base64; +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.HttpHost; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.conn.routing.HttpRoutePlanner; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.conn.ssl.TrustStrategy; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.DefaultProxyRoutePlanner; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.ssl.SSLContexts; +import org.apache.http.util.EntityUtils; +import org.gluu.model.net.HttpServiceResponse; +import org.gluu.util.StringHelper; +import org.gluu.util.Util; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +/** + * Provides operations with http requests + * + * @author Yuriy Movchan Date: 02/05/2013 + */ +public class HttpServiceUtility implements Serializable { + + private static final long serialVersionUID = -2398422090669045605L; + + private static final Logger LOG = LoggerFactory.getLogger(HttpServiceUtility.class); + + private Base64 base64; + + private PoolingHttpClientConnectionManager connectionManager; + + public void init() { + connectionManager = new PoolingHttpClientConnectionManager(); + connectionManager.setMaxTotal(200); // Increase max total connection to 200 + connectionManager.setDefaultMaxPerRoute(50); // Increase default max connection per route to 50 + + this.base64 = new Base64(); + } + + public void destroy() { + if (connectionManager != null) { + connectionManager.shutdown(); + } + } + + public CloseableHttpClient getHttpsClientTrustAll() throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException { + getLogger().trace("Connection manager stats: {}", connectionManager.getTotalStats()); + + TrustStrategy acceptingTrustStrategy = (cert, authType) -> true; + SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build(); + SSLConnectionSocketFactory sslConSocFactory = new SSLConnectionSocketFactory(sslContext, + NoopHostnameVerifier.INSTANCE); + + return HttpClients.custom().setSSLSocketFactory(sslConSocFactory) + .setDefaultRequestConfig(RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build()) + .setConnectionManager(connectionManager).build(); + } + + public CloseableHttpClient getHttpsClient() { + getLogger().trace("Connection manager stats: {}", connectionManager.getTotalStats()); + + return HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build()) + .setConnectionManager(connectionManager).build(); + } + + public CloseableHttpClient getHttpsClient(HttpRoutePlanner routerPlanner) { + getLogger().trace("Connection manager stats: {}", connectionManager.getTotalStats()); + + return HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build()) + .setConnectionManager(connectionManager).setRoutePlanner(routerPlanner).build(); + + } + + public CloseableHttpClient getHttpsClient(String trustStoreType, String trustStorePath, String trustStorePassword) throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException { + getLogger().trace("Connection manager stats: {}", connectionManager.getTotalStats()); + + SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(new File(trustStorePath), trustStorePassword.toCharArray()).build(); + SSLConnectionSocketFactory sslConSocFactory = new SSLConnectionSocketFactory(sslContext); + + return HttpClients.custom().setSSLSocketFactory(sslConSocFactory) + .setDefaultRequestConfig(RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build()) + .setConnectionManager(connectionManager).build(); + } + + public CloseableHttpClient getHttpsClient(String trustStoreType, String trustStorePath, String trustStorePassword, + String keyStoreType, String keyStorePath, String keyStorePassword) throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException, UnrecoverableKeyException { + getLogger().trace("Connection manager stats: {}", connectionManager.getTotalStats()); + + SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(new File(trustStorePath), trustStorePassword.toCharArray()) + .loadKeyMaterial(new File(keyStorePath), keyStorePassword.toCharArray(), keyStorePassword.toCharArray()).build(); + SSLConnectionSocketFactory sslConSocFactory = new SSLConnectionSocketFactory(sslContext); + + return HttpClients.custom().setSSLSocketFactory(sslConSocFactory) + .setDefaultRequestConfig(RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build()) + .setConnectionManager(connectionManager).build(); + } + + public HttpServiceResponse executePost(HttpClient httpClient, String uri, String authData, Map headers, String postData, ContentType contentType) { + HttpPost httpPost = new HttpPost(uri); + if (StringHelper.isNotEmpty(authData)) { + httpPost.setHeader("Authorization", "Basic " + authData); + } + + if (headers != null) { + for (Entry headerEntry : headers.entrySet()) { + httpPost.setHeader(headerEntry.getKey(), headerEntry.getValue()); + } + } + + StringEntity stringEntity = new StringEntity(postData, contentType); + httpPost.setEntity(stringEntity); + + try { + HttpResponse httpResponse = httpClient.execute(httpPost); + + return new HttpServiceResponse(httpPost, httpResponse); + } catch (IOException ex) { + getLogger().error("Failed to execute post request", ex); + } + + return null; + } + + public HttpServiceResponse executePost(HttpClient httpClient, String uri, String authData, Map headers, String postData) { + return executePost(httpClient, uri, authData, headers, postData, null); + } + + public HttpServiceResponse executePost(HttpClient httpClient, String uri, String authData, String postData, ContentType contentType) { + return executePost(httpClient, uri, authData, null, postData, contentType); + } + + public String encodeBase64(String value) { + try { + return new String(base64.encode((value).getBytes(Util.UTF8)), Util.UTF8); + } catch (UnsupportedEncodingException ex) { + getLogger().error("Failed to convert '{}' to base64", value, ex); + } + + return null; + } + + public String encodeUrl(String value) { + try { + return URLEncoder.encode(value, Util.UTF8); + } catch (UnsupportedEncodingException ex) { + getLogger().error("Failed to encode url '{}'", value, ex); + } + + return null; + } + + public HttpServiceResponse executeGet(HttpClient httpClient, String requestUri, Map headers) { + HttpGet httpGet = new HttpGet(requestUri); + + if (headers != null) { + for (Entry headerEntry : headers.entrySet()) { + httpGet.setHeader(headerEntry.getKey(), headerEntry.getValue()); + } + } + + try { + HttpResponse httpResponse = httpClient.execute(httpGet); + + return new HttpServiceResponse(httpGet, httpResponse); + } catch (IOException ex) { + getLogger().error("Failed to execute get request", ex); + } + + return null; + } + + public HttpServiceResponse executeGet(HttpClient httpClient, String requestUri) throws ClientProtocolException, IOException { + return executeGet(httpClient, requestUri, null); + } + + public byte[] getResponseContent(HttpResponse httpResponse) throws IOException { + if ((httpResponse == null) || !isResponseStastusCodeOk(httpResponse)) { + return null; + } + + HttpEntity entity = httpResponse.getEntity(); + byte[] responseBytes = new byte[0]; + if (entity != null) { + responseBytes = EntityUtils.toByteArray(entity); + } + + // Consume response content + if (entity != null) { + EntityUtils.consume(entity); + } + + return responseBytes; + } + + public void consume(HttpResponse httpResponse) throws IOException { + if ((httpResponse == null) || !isResponseStastusCodeOk(httpResponse)) { + return; + } + + // Consume response content + HttpEntity entity = httpResponse.getEntity(); + if (entity != null) { + EntityUtils.consume(entity); + } + } + + public String convertEntityToString(byte[] responseBytes) { + if (responseBytes == null) { + return null; + } + + return new String(responseBytes); + } + + public String convertEntityToString(byte[] responseBytes, Charset charset) { + if (responseBytes == null) { + return null; + } + + return new String(responseBytes, charset); + } + + public String convertEntityToString(byte[] responseBytes, String charsetName) throws UnsupportedEncodingException { + if (responseBytes == null) { + return null; + } + + return new String(responseBytes, charsetName); + } + + public boolean isResponseStastusCodeOk(HttpResponse httpResponse) { + int responseStastusCode = httpResponse.getStatusLine().getStatusCode(); + if ((responseStastusCode == HttpStatus.SC_OK) || (responseStastusCode == HttpStatus.SC_CREATED) || (responseStastusCode == HttpStatus.SC_ACCEPTED) + || (responseStastusCode == HttpStatus.SC_NON_AUTHORITATIVE_INFORMATION) || (responseStastusCode == HttpStatus.SC_NO_CONTENT) || (responseStastusCode == HttpStatus.SC_RESET_CONTENT) + || (responseStastusCode == HttpStatus.SC_PARTIAL_CONTENT) || (responseStastusCode == HttpStatus.SC_MULTI_STATUS)) { + return true; + } + + return false; + } + + public boolean isContentTypeXml(HttpResponse httpResponse) { + Header contentType = httpResponse.getEntity().getContentType(); + if (contentType == null) { + return false; + } + + String contentTypeValue = contentType.getValue(); + if (StringHelper.equals(contentTypeValue, ContentType.APPLICATION_XML.getMimeType()) || StringHelper.equals(contentTypeValue, ContentType.TEXT_XML.getMimeType())) { + return true; + } + + return false; + } + + public String constructServerUrl(final HttpServletRequest request) { + int serverPort = request.getServerPort(); + + String redirectUrl; + if ((serverPort == 80) || (serverPort == 443)) { + redirectUrl = String.format("%s://%s%s", request.getScheme(), request.getServerName(), request.getContextPath()); + } else { + redirectUrl = String.format("%s://%s:%s%s", request.getScheme(), request.getServerName(), request.getServerPort(), request.getContextPath()); + } + + return redirectUrl.toLowerCase(); + } + + public HttpRoutePlanner buildDefaultRoutePlanner(final String proxy) { + //Creating an HttpHost object for proxy + HttpHost proxyHost = new HttpHost(proxy); + + return new DefaultProxyRoutePlanner(proxyHost); + } + + public Logger getLogger() { + return LOG; + } + +} diff --git a/oxUtil/src/main/java/org/gluu/net/ProxyUtil.java b/oxUtil/src/main/java/org/gluu/net/ProxyUtil.java new file mode 100644 index 000000000..fa9e35c44 --- /dev/null +++ b/oxUtil/src/main/java/org/gluu/net/ProxyUtil.java @@ -0,0 +1,17 @@ +package org.gluu.net; + +import org.apache.commons.lang3.StringUtils; + +/** + * Proxy utilities + * + * @author Yuriy Movchan + * @version 1.0, 08/27/2021 + */ +public class ProxyUtil { + + public static boolean isProxyRequied() { + return (StringUtils.isNotBlank(System.getProperty("http.proxyHost")) && StringUtils.isNotBlank(System.getProperty("http.proxyPort"))) + || (StringUtils.isNotBlank(System.getProperty("https.proxyHost")) && StringUtils.isNotBlank(System.getProperty("https.proxyPort"))); + } +} diff --git a/oxUtil/src/main/java/org/gluu/util/EasySSLProtocolSocketFactory.java b/oxUtil/src/main/java/org/gluu/util/EasySSLProtocolSocketFactory.java deleted file mode 100644 index 9a5be686a..000000000 --- a/oxUtil/src/main/java/org/gluu/util/EasySSLProtocolSocketFactory.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.util; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.net.SocketAddress; -import java.net.UnknownHostException; - -import javax.net.SocketFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManager; - -import org.apache.commons.httpclient.ConnectTimeoutException; -import org.apache.commons.httpclient.HttpClientError; -import org.apache.commons.httpclient.params.HttpConnectionParams; -import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - *

- * EasySSLProtocolSocketFactory can be used to creats SSL {@link Socket}s that - * accept self-signed certificates. - *

- *

- * This socket factory SHOULD NOT be used for productive systems due to security - * reasons, unless it is a concious decision and you are perfectly aware of - * security implications of accepting self-signed certificates - *

- * - *

- * Example of using custom protocol socket factory for a specific host: - * - *

- * Protocol easyhttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443);
- *
- * URI uri = new URI("https://localhost/", true);
- * // use relative url only
- * GetMethod httpget = new GetMethod(uri.getPathQuery());
- * HostConfiguration hc = new HostConfiguration();
- * hc.setHost(uri.getHost(), uri.getPort(), easyhttps);
- * HttpClient client = new HttpClient();
- * client.executeMethod(hc, httpget);
- * 
- * - *

- *

- * Example of using custom protocol socket factory per default instead of the - * standard one: - * - *

- * Protocol easyhttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443);
- * Protocol.registerProtocol("https", easyhttps);
- *
- * HttpClient client = new HttpClient();
- * GetMethod httpget = new GetMethod("https://localhost/");
- * client.executeMethod(httpget);
- * 
- * - *

- * - * @author Oleg Kalnichevski - * - *

- * DISCLAIMER: HttpClient developers DO NOT actively support this - * component. The component is provided as a reference material, which - * may be inappropriate for use without additional customization. - *

- */ - -public class EasySSLProtocolSocketFactory implements ProtocolSocketFactory { - - /** Log object for this class. */ - private static final Log LOG = LogFactory.getLog(EasySSLProtocolSocketFactory.class); - - private SSLContext sslcontext = null; - - /** - * Constructor for EasySSLProtocolSocketFactory. - */ - public EasySSLProtocolSocketFactory() { - super(); - } - - protected SSLContext createEasySSLContext() { - try { - SSLContext context = SSLContext.getInstance("SSL"); - context.init(null, new TrustManager[] {new EasyX509TrustManager(null)}, null); - return context; - } catch (Exception e) { - LOG.error(e.getMessage(), e); - throw new HttpClientError(e.toString()); - } - } - - private SSLContext getSSLContext() { - if (this.sslcontext == null) { - this.sslcontext = createEasySSLContext(); - } - return this.sslcontext; - } - - /** - * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int,java.net.InetAddress,int) - */ - public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) - throws IOException, UnknownHostException { - - return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort); - } - - /** - * Attempts to get a new socket connection to the given host within the given - * time limit. - *

- * To circumvent the limitations of older JREs that do not support connect - * timeout a controller thread is executed. The controller thread attempts to - * create a new socket within the given limit of time. If socket constructor - * does not return until the timeout expires, the controller terminates and - * throws an {@link ConnectTimeoutException} - *

- * - * @param host - * the host name/IP - * @param port - * the port on the host - * @param localAddress - * the local host name/IP to bind the socket to - * @param localPort - * the port on the local machine - * @param params - * {@link HttpConnectionParams Http connection parameters} - * - * @return Socket a new socket - * - * @throws IOException - * if an I/O error occurs while creating the socket - * @throws UnknownHostException - * if the IP address of the host cannot be determined - */ - public Socket createSocket(final String host, final int port, final InetAddress localAddress, final int localPort, - final HttpConnectionParams params) throws IOException, UnknownHostException, ConnectTimeoutException { - if (params == null) { - throw new IllegalArgumentException("Parameters may not be null"); - } - int timeout = params.getConnectionTimeout(); - SocketFactory socketfactory = getSSLContext().getSocketFactory(); - if (timeout == 0) { - return socketfactory.createSocket(host, port, localAddress, localPort); - } else { - Socket socket = socketfactory.createSocket(); - SocketAddress localaddr = new InetSocketAddress(localAddress, localPort); - SocketAddress remoteaddr = new InetSocketAddress(host, port); - socket.bind(localaddr); - socket.connect(remoteaddr, timeout); - return socket; - } - } - - /** - * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int) - */ - public Socket createSocket(String host, int port) throws IOException, UnknownHostException { - return getSSLContext().getSocketFactory().createSocket(host, port); - } - - /** - * @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean) - */ - public Socket createSocket(Socket socket, String host, int port, boolean autoClose) - throws IOException, UnknownHostException { - return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose); - } - - // public boolean equals(Object obj) { - // return ((obj != null) && - // obj.getClass().equals(EasySSLProtocolSocketFactory.class)); - // } - - // public int hashCode() { - // return EasySSLProtocolSocketFactory.class.hashCode(); - // } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - EasySSLProtocolSocketFactory that = (EasySSLProtocolSocketFactory) o; - - if (sslcontext != null ? !sslcontext.equals(that.sslcontext) : that.sslcontext != null) { - return false; - } - - return true; - } - - @Override - public int hashCode() { - return sslcontext != null ? sslcontext.hashCode() : 0; - } -} diff --git a/oxUtil/src/main/java/org/gluu/util/OxConstants.java b/oxUtil/src/main/java/org/gluu/util/OxConstants.java new file mode 100644 index 000000000..1e5da00c6 --- /dev/null +++ b/oxUtil/src/main/java/org/gluu/util/OxConstants.java @@ -0,0 +1,39 @@ +/* + * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2014, Gluu + */package org.gluu.util; + +/** + * Constants loads the LDAP schema attribute names like uid, iname + * + * @author Yuriy Movchan + * @version 0.1, 10/14/2010 + */ +public class OxConstants { + + public static final String UID = "uid"; + public static final String OBJECT_CLASS = "objectClass"; + + public static final String INUM = "inum"; + public static final String INAME = "iname"; + public static final String DISPLAY_NAME = "displayName"; + public static final String SCRIPT_TYPE = "oxScriptType"; + public static final String DESCRIPTION = "description"; + public static final String ORIGIN = "gluuAttributeOrigin"; + public static final String MAIL = "mail"; + + public static final String CACHE_ORGANIZATION_KEY = "organization"; + public static final String CACHE_METRICS_KEY = "metrics"; + public static final String CACHE_APPLICATION_NAME = "ApplicationCache"; + public static final String CACHE_ATTRIBUTE_NAME = "AttributeCache"; + public static final String CACHE_LOOKUP_NAME = "LookupCache"; + public static final String CACHE_METRICS_NAME = "metricsCache"; + + public static final String CACHE_ATTRIBUTE_KEY_LIST = "attributeList"; + public static final String CACHE_ACTIVE_ATTRIBUTE_KEY_LIST = "activeAttributeList"; + public static final String CACHE_ACTIVE_ATTRIBUTE_NAME = "ActiveAttributeCache"; + + public static final String SCRIPT_TYPE_INTERNAL_RESERVED_NAME = "simple_password_auth"; + +} diff --git a/oxUtil/src/main/java/org/gluu/util/SelectableEntityHelper.java b/oxUtil/src/main/java/org/gluu/util/SelectableEntityHelper.java index b57a62a21..a25294d6a 100644 --- a/oxUtil/src/main/java/org/gluu/util/SelectableEntityHelper.java +++ b/oxUtil/src/main/java/org/gluu/util/SelectableEntityHelper.java @@ -6,13 +6,13 @@ package org.gluu.util; +import org.gluu.model.SelectableEntity; + import java.util.ArrayList; import java.util.List; -import org.gluu.model.SelectableEntity; - /** - * Converts lis of entities to list of selectable entities + * Converts list of entities to list of selectable entities * * @author Yuriy Movchan Date: 04/25/2013 */ @@ -40,4 +40,9 @@ public static List convertToEntities(List> selectable return result; } + public static void select(List> selectableEntities, List entities) { + for (SelectableEntity selectable : selectableEntities) { + selectable.setSelected(entities.contains(selectable.getEntity())); + } + } } diff --git a/oxUtil/src/main/java/org/gluu/util/StringHelper.java b/oxUtil/src/main/java/org/gluu/util/StringHelper.java index 35e8211b1..85eeb7ec0 100644 --- a/oxUtil/src/main/java/org/gluu/util/StringHelper.java +++ b/oxUtil/src/main/java/org/gluu/util/StringHelper.java @@ -136,7 +136,7 @@ public static String[] toStringArray(Object[] array) { String[] result = new String[array.length]; for (int i = 0; i < result.length; i++) { - result[i] = String.valueOf(array[i]); + result[i] = toString(array[i]); } return result; @@ -514,11 +514,19 @@ public static boolean isEmptyString(Object string) { } public static boolean isNotEmptyString(Object string) { + if (string == null) { + return false; + } + return !(string instanceof String) || isNotEmpty((String) string); } public static String toString(Object object) { - return (object == null) ? null : object.toString(); + if (object instanceof String) { + return (String) object; + } + + return (object == null) ? null : object.toString(); } public static String qualify(final String prefix, String name) { diff --git a/oxUtil/src/main/java/org/gluu/util/init/Initializable.java b/oxUtil/src/main/java/org/gluu/util/init/Initializable.java index 2cced6ae5..04b60a663 100644 --- a/oxUtil/src/main/java/org/gluu/util/init/Initializable.java +++ b/oxUtil/src/main/java/org/gluu/util/init/Initializable.java @@ -43,4 +43,7 @@ public boolean isInitialized() { protected abstract void initInternal(); + protected void resetInitialized() { + this.initialized = false; + } } diff --git a/oxUtil/src/main/java/org/gluu/util/io/HTTPFileDownloader.java b/oxUtil/src/main/java/org/gluu/util/io/HTTPFileDownloader.java deleted file mode 100644 index 0fa4d51c6..000000000 --- a/oxUtil/src/main/java/org/gluu/util/io/HTTPFileDownloader.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.util.io; - -import java.io.IOException; - -import org.apache.commons.httpclient.Credentials; -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.HttpStatus; -import org.apache.commons.httpclient.UsernamePasswordCredentials; -import org.apache.commons.httpclient.auth.AuthScope; -import org.apache.commons.httpclient.methods.GetMethod; -import org.apache.commons.httpclient.protocol.Protocol; -import org.gluu.util.EasySSLProtocolSocketFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author: Yuriy Movchan Date: 11.21.2010 - */ -public final class HTTPFileDownloader { - - private HTTPFileDownloader() { } - - private static final Logger LOG = LoggerFactory.getLogger(HTTPFileDownloader.class); - private static Protocol EASY_HTTPS; - - public static String getResource(String path, String contentType, String user, String password) { - boolean isUseAuthentication = (user != null) && (password != null); - - if (!path.contains("://")) { - path = "http://" + path; - } - String result = null; - - GetMethod method = new GetMethod(path); - try { - method.setRequestHeader("Accept", contentType); - - if (getEasyhttps() == null) { - setEasyhttps(new Protocol("https", new EasySSLProtocolSocketFactory(), 443)); - } - Protocol.registerProtocol("https", getEasyhttps()); - - final HttpClient httpClient; - if (isUseAuthentication) { - httpClient = createHttpClientWithBasicAuth(user, password); - } else { - httpClient = new HttpClient(); - } - - httpClient.executeMethod(method); - if (method.getStatusCode() == HttpStatus.SC_OK) { - result = method.getResponseBodyAsString(); - } - } catch (IOException ex) { - result = null; - LOG.error(String.format("Failed to get resource %s", path), ex); - } catch (Exception ex) { - result = null; - LOG.error(String.format("Failed to get resource %s", path), ex); - } finally { - method.releaseConnection(); - } - - return result; - } - - private static HttpClient createHttpClientWithBasicAuth(String userid, String password) { - Credentials credentials = new UsernamePasswordCredentials(userid, password); - HttpClient httpClient = new HttpClient(); - httpClient.getState().setCredentials(AuthScope.ANY, credentials); - httpClient.getParams().setAuthenticationPreemptive(true); - return httpClient; - } - - public static void setEasyhttps(Protocol easyhttps) { - HTTPFileDownloader.EASY_HTTPS = easyhttps; - } - - public static Protocol getEasyhttps() { - return EASY_HTTPS; - } - -} diff --git a/oxUtil/src/main/java/org/gluu/util/locale/LocaleUtil.java b/oxUtil/src/main/java/org/gluu/util/locale/LocaleUtil.java new file mode 100644 index 000000000..baec7e396 --- /dev/null +++ b/oxUtil/src/main/java/org/gluu/util/locale/LocaleUtil.java @@ -0,0 +1,58 @@ +/* + * oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2014, Gluu + */ + +package org.gluu.util.locale; + +import java.util.List; +import java.util.Locale; + +import org.apache.commons.lang.LocaleUtils; +import org.apache.commons.lang3.tuple.Pair; + +/** + * @author Javier Rojas Blum Date: 11.27.2013 + * @author Yuriy Movchan Date: 02/28/2020 + */ +public class LocaleUtil { + + public static Locale localeMatch(List requestedLocales, List availableLocales) { + if (requestedLocales == null || availableLocales == null) { + return null; + } + + for (String requestedLocale : requestedLocales) { + Pair> locales = toLocaleList(requestedLocale); + Locale reqInQuestion = locales.getLeft(); + List lookupList = locales.getRight(); + + for (Locale localeInQuestion : lookupList) { + for (Locale availableLocale : availableLocales) { + if (localeInQuestion.equals(availableLocale)) { + return availableLocale; + } + } + } + + for (Locale availableLocale : availableLocales) { + if (reqInQuestion.getLanguage().equals(availableLocale.getLanguage())) { + return availableLocale; + } + } + } + + return null; + } + + public static Pair> toLocaleList(String locale) { + // LocaleUtils uses an underscore format (e.g. en_US), but the new Java standard + // is a hyphenated format (e.g. en-US). This allows us to use LocaleUtils' validation. + Locale localeLanguage = LocaleUtils.toLocale(locale.replace('-', '_')); + List localeList = LocaleUtils.localeLookupList(localeLanguage); + + return Pair.of(localeLanguage, localeList); + } + +} \ No newline at end of file diff --git a/oxUtil/src/main/java/org/gluu/util/security/AESUtil.java b/oxUtil/src/main/java/org/gluu/util/security/AESUtil.java new file mode 100644 index 000000000..7cdd8d440 --- /dev/null +++ b/oxUtil/src/main/java/org/gluu/util/security/AESUtil.java @@ -0,0 +1,89 @@ +package org.gluu.util.security; + +import javax.crypto.*; +import javax.crypto.spec.GCMParameterSpec; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.SecretKeySpec; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; +import java.util.Base64; + +public class AESUtil { + + public static final int IV_LENGTH = 16; + public static final int GCM_TAG_LENGTH = 16; + + public static SecretKey generateKey(int n) throws NoSuchAlgorithmException { + KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); + keyGenerator.init(n); + return keyGenerator.generateKey(); + } + + public static SecretKey getKeyFromPassword(String password, String salt) + throws NoSuchAlgorithmException, InvalidKeySpecException { + SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); + KeySpec spec = new PBEKeySpec(password.toCharArray(), salt.getBytes(), 65536, 256); + return new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES"); + } + + public static IvParameterSpec generateIv() { + return generateIv(IV_LENGTH); + } + + public static IvParameterSpec generateIv(int size) { + byte[] iv = new byte[size]; + new SecureRandom().nextBytes(iv); + return new IvParameterSpec(iv); + } + + public static GCMParameterSpec generateGcmSpec() { + return new GCMParameterSpec(GCM_TAG_LENGTH * 8, generateIv().getIV()); + } + + + public static String encrypt(String algorithm, String input, SecretKey key, AlgorithmParameterSpec spec) throws NoSuchPaddingException, NoSuchAlgorithmException, + InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { + + Cipher cipher = Cipher.getInstance(algorithm); + cipher.init(Cipher.ENCRYPT_MODE, key, spec); + byte[] cipherText = cipher.doFinal(input.getBytes()); + return Base64.getEncoder().encodeToString(cipherText); + } + + public static String decrypt(String algorithm, String cipherText, SecretKey key, AlgorithmParameterSpec spec) throws NoSuchPaddingException, NoSuchAlgorithmException, + InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { + Cipher cipher = Cipher.getInstance(algorithm); + cipher.init(Cipher.DECRYPT_MODE, key, spec); + byte[] plainText = cipher.doFinal(Base64.getDecoder().decode(cipherText)); + return new String(plainText); + } + + /* + public static void main(String[] args) throws NoSuchPaddingException, InvalidKeyException, NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException { + String input = "textToEncrypt"; + SecretKey key = AESUtil.generateKey(128); + IvParameterSpec ivParameterSpec = AESUtil.generateIv(); + + // CBC + String algorithm = "AES/CBC/PKCS5Padding"; + String cipherText = AESUtil.encrypt(algorithm, input, key, ivParameterSpec); + String plainText = AESUtil.decrypt(algorithm, cipherText, key, ivParameterSpec); + boolean equals = input.equals(plainText); + System.out.println(equals); + + // GCM + algorithm = "AES/GCM/NoPadding"; + final GCMParameterSpec gcmSpec = generateGcmSpec(); + cipherText = AESUtil.encrypt(algorithm, input, key, gcmSpec); + plainText = AESUtil.decrypt(algorithm, cipherText, key, gcmSpec); + equals = input.equals(plainText); + System.out.println(equals); + } + */ +} diff --git a/oxUtil/src/main/java/org/gluu/util/security/SecurityProviderUtility.java b/oxUtil/src/main/java/org/gluu/util/security/SecurityProviderUtility.java new file mode 100644 index 000000000..9ad58d4f3 --- /dev/null +++ b/oxUtil/src/main/java/org/gluu/util/security/SecurityProviderUtility.java @@ -0,0 +1,366 @@ +/* + * oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2014, Gluu + */ + +package org.gluu.util.security; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.nio.charset.StandardCharsets; +import java.security.NoSuchAlgorithmException; +import java.security.Provider; +import java.security.Security; +import java.util.List; + +import javax.crypto.Cipher; + +import org.apache.commons.io.IOUtils; +import org.gluu.util.StringHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Provider installation utility + * + * @author Yuriy Movchan + * @author madhumitas + * @author Sergey Manoylo + * @version April 26, 2022 + */ +public class SecurityProviderUtility { + + // security mode + public static final String DEF_MODE_BCPROV = "BCPROV"; + public static final String DEF_MODE_BCFIPS = "BCFIPS"; + + // keystorage type + public static final String DEF_KS_JKS = "JKS"; + public static final String DEF_KS_PKCS12 = "PKCS12"; + public static final String DEF_KS_BCFKS = "BCFKS"; + + // JKS additional extensions + public static final String DEF_EXT_JKS = "jks"; + public static final String DEF_EXT_KEYSTORE = "keystore"; + public static final String DEF_EXT_KS = "ks"; + + // PKCS12 additional extensions + public static final String DEF_EXT_PKCS12 = "pkcs12"; + public static final String DEF_EXT_P12 = "p12"; + public static final String DEF_EXT_PFX = "pfx"; + + // BCFKS additional extensions + public static final String DEF_EXT_BCFKS = "bcfks"; + public static final String DEF_EXT_BCF = "bcf"; + public static final String DEF_EXT_BCFIPS = "bcfips"; + + /** + * Security Mode Type + * + * @author Sergey Manoylo + * @version March 11, 2022 + */ + public static enum SecurityModeType { + + BCPROV_SECURITY_MODE (DEF_MODE_BCPROV), + BCFIPS_SECURITY_MODE (DEF_MODE_BCFIPS); + + private final String value; + + /** + * Constructor + * + * @param value string value, that defines Security Mode Type + */ + SecurityModeType(String value) { + this.value = value; + } + + /** + * Creates/parses SecurityModeType from String value + * + * @param param string value, that defines Security Mode Type + * @return SecurityModeType + */ + public static SecurityModeType fromString(String param) { + switch(param.toUpperCase()) { + case DEF_MODE_BCPROV: { + return BCPROV_SECURITY_MODE; + } + case DEF_MODE_BCFIPS: { + return BCFIPS_SECURITY_MODE; + } + } + return null; + } + + /** + * Returns a string representation of the object. In this case the parameter name for the default scope. + */ + @Override + public String toString() { + return value; + } + + /** + * + * @return + */ + public KeyStorageType[] getKeystorageTypes() { + KeyStorageType [] keystorages = null; + if (this == BCPROV_SECURITY_MODE) { + keystorages = new KeyStorageType[] { KeyStorageType.JKS_KS, KeyStorageType.PKCS12_KS }; + } + else if (this == BCFIPS_SECURITY_MODE) { + keystorages = new KeyStorageType[] { KeyStorageType.BCFKS_KS }; + } + return keystorages; + } + } + + /** + * Security Mode Type + * + * @author Sergey Manoylo + * @version March 11, 2022 + */ + public static enum KeyStorageType { + + JKS_KS (DEF_KS_JKS), + PKCS12_KS (DEF_KS_PKCS12), + BCFKS_KS (DEF_KS_BCFKS); + + private final String value; + + /** + * Constructor + * + * @param value string value, that defines Security Mode Type + */ + KeyStorageType(String value) { + this.value = value; + } + + /** + * Creates/parses SecurityModeType from String value + * + * @param param string value, that defines Security Mode Type + * @return SecurityModeType + */ + public static KeyStorageType fromString(String param) { + switch(param.toUpperCase()) { + case DEF_KS_JKS: { + return JKS_KS; + } + case DEF_KS_PKCS12: { + return PKCS12_KS; + } + case DEF_KS_BCFKS: { + return BCFKS_KS; + } + } + return null; + } + + /** + * Returns a string representation of the object. In this case the parameter name for the default scope. + */ + @Override + public String toString() { + return value; + } + + /** + * + * @return + */ + public String[] getExtensions() { + String[] extensions = null; + if (this == JKS_KS) { + extensions = new String[] { DEF_EXT_JKS, DEF_EXT_KEYSTORE, DEF_EXT_KS }; + } + else if(this == PKCS12_KS) { + extensions = new String[] { DEF_EXT_PKCS12, DEF_EXT_P12, DEF_EXT_P12 }; + } + else if(this == BCFKS_KS) { + extensions = new String[] { DEF_EXT_BCFKS, DEF_EXT_BCF, DEF_EXT_BCFIPS }; + } + return extensions; + } + + /** + * + * @return + */ + public SecurityModeType getSecurityMode() { + SecurityModeType securityModeType = null; + if (this == JKS_KS || this == PKCS12_KS) { + securityModeType = SecurityModeType.BCPROV_SECURITY_MODE; + } + else if(this == BCFKS_KS) { + securityModeType = SecurityModeType.BCFIPS_SECURITY_MODE; + } + return securityModeType; + } + + /** + * + * @param extension + * @return + */ + public static KeyStorageType fromExtension(String extension) { + switch(extension.toLowerCase()) { + case DEF_EXT_JKS: + case DEF_EXT_KEYSTORE: + case DEF_EXT_KS: { + return JKS_KS; + } + case DEF_EXT_PKCS12: + case DEF_EXT_P12: + case DEF_EXT_PFX: { + return PKCS12_KS; + } + case DEF_EXT_BCFKS: + case DEF_EXT_BCF: + case DEF_EXT_BCFIPS: { + return BCFKS_KS; + } + } + return null; + } + } + + private static final Logger LOG = LoggerFactory.getLogger(SecurityProviderUtility.class); + + public static final String BC_PROVIDER_NAME = "BC"; + public static final String BC_FIPS_PROVIDER_NAME = "BCFIPS"; + + public static boolean USE_FIPS_CHECK_COMMAND = false; + + private static SecurityModeType securityMode = null; + + private static Provider bouncyCastleProvider; + + private static final String BC_GENERIC_PROVIDER_CLASS_NAME = "org.bouncycastle.jce.provider.BouncyCastleProvider"; + private static final String BC_FIPS_PROVIDER_CLASS_NAME = "org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider"; + + public static void installBCProvider(boolean silent) { + String providerName = BC_PROVIDER_NAME; + String className = BC_GENERIC_PROVIDER_CLASS_NAME; + + if (securityMode == null || securityMode == SecurityModeType.BCFIPS_SECURITY_MODE) { + boolean isFipsMode = checkFipsMode(); + if (isFipsMode) { + LOG.info("Fips mode is enabled"); + + providerName = BC_FIPS_PROVIDER_NAME; + className = BC_FIPS_PROVIDER_CLASS_NAME; + + securityMode = SecurityModeType.BCFIPS_SECURITY_MODE; + } + else { + securityMode = SecurityModeType.BCPROV_SECURITY_MODE; + } + } + + try { + installBCProvider(providerName, className, silent); + } catch (Exception e) { + LOG.error( + "Security provider '{}' doesn't exists in class path. Please deploy correct war for this environment!", providerName); + LOG.error(e.getMessage(), e); + } + } + + public static void installBCProvider() { + installBCProvider(false); + } + + public static void installBCProvider(String providerName, String providerClassName, boolean silent) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, ClassNotFoundException { + bouncyCastleProvider = Security.getProvider(providerName); + if (bouncyCastleProvider == null) { + if (!silent) { + LOG.info("Adding Bouncy Castle Provider"); + } + + bouncyCastleProvider = (Provider) Class.forName(providerClassName).getConstructor().newInstance(); + Security.addProvider(bouncyCastleProvider); + LOG.info("Provider '{}' with version {} is added", bouncyCastleProvider.getName(), bouncyCastleProvider.getVersionStr()); + } else { + if (!silent) { + LOG.info("Bouncy Castle Provider was added already"); + } + } + } + + /** + * A check that the server is running in FIPS-approved-only mode. This is a part + * of compliance to ensure that the server is really FIPS compliant + * + * @return boolean value + */ + private static boolean checkFipsMode() { + try { + // First check if there are FIPS provider libs + Class.forName(BC_FIPS_PROVIDER_CLASS_NAME); + } catch (ClassNotFoundException e) { + LOG.trace("BC Fips provider is not available", e); + return false; + } + + if (USE_FIPS_CHECK_COMMAND) { + String osName = System.getProperty("os.name"); + if (StringHelper.isNotEmpty(osName) && osName.toLowerCase().startsWith("windows")) { + return false; + } + + try { + // Check if FIPS is enabled + Process process = Runtime.getRuntime().exec("fips-mode-setup --check"); + List result = IOUtils.readLines(process.getInputStream(), StandardCharsets.UTF_8); + if ((result.size() > 0) && StringHelper.equalsIgnoreCase(result.get(0), "FIPS mode is enabled.")) { + return true; + } + } catch (IOException e) { + LOG.error("Failed to check if FIPS mode was enabled", e); + return false; + } + return false; + } + + return true; + } + + /** + * Determines if cryptography restrictions apply. + * Restrictions apply if the value of {@link Cipher#getMaxAllowedKeyLength(String)} returns a value smaller than {@link Integer#MAX_VALUE} if there are any restrictions according to the JavaDoc of the method. + * This method is used with the transform "AES/CBC/PKCS5Padding" as this is an often used algorithm that is an implementation requirement for Java SE. + * + * @return true if restrictions apply, false otherwise + * https://stackoverflow.com/posts/33849265/edit, author Maarten Bodewes + */ + public static boolean checkRestrictedCryptography() { + try { + return Cipher.getMaxAllowedKeyLength("AES/CBC/PKCS5Padding") < Integer.MAX_VALUE; + } catch (final NoSuchAlgorithmException e) { + throw new IllegalStateException("The transform \"AES/CBC/PKCS5Padding\" is not available (the availability of this algorithm is mandatory for Java SE implementations)", e); + } + } + + public static String getBCProviderName() { + return bouncyCastleProvider.getName(); + } + + public static Provider getBCProvider() { + return bouncyCastleProvider; + } + + public static SecurityModeType getSecurityMode() { + return securityMode; + } + + public static void setSecurityMode(SecurityModeType securityModeIn) { + securityMode = securityModeIn; + } +} diff --git a/oxUtil/src/main/java/org/gluu/util/security/StringEncrypter.java b/oxUtil/src/main/java/org/gluu/util/security/StringEncrypter.java index ef64ad28d..e1abf9419 100644 --- a/oxUtil/src/main/java/org/gluu/util/security/StringEncrypter.java +++ b/oxUtil/src/main/java/org/gluu/util/security/StringEncrypter.java @@ -108,12 +108,8 @@ public EncryptionException(final Throwable t) { * Byte stream * @return String representation */ - private static String bytes2String(final byte[] bytes) { - final StringBuffer stringBuffer = new StringBuffer(); - for (final byte element : bytes) { - stringBuffer.append((char) element); - } - return stringBuffer.toString(); + private static String bytes2String(final byte[] bytes) throws UnsupportedEncodingException { + return new String(bytes, Util.UTF8); } /** @@ -210,7 +206,7 @@ private String decrypt(final String encryptedString, KeySpec keySpec, boolean si final byte[] cleartext = base64.decode(encryptedString.getBytes(Util.UTF8)); final byte[] ciphertext = cipher.doFinal(cleartext); - return StringEncrypter.bytes2String(ciphertext); + return bytes2String(ciphertext); } catch (final Exception e) { if (silent) { return encryptedString; diff --git a/oxUtil/src/main/java/org/gluu/xml/SimpleNamespaceContext.java b/oxUtil/src/main/java/org/gluu/xml/SimpleNamespaceContext.java deleted file mode 100644 index f653b2a68..000000000 --- a/oxUtil/src/main/java/org/gluu/xml/SimpleNamespaceContext.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.xml; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import javax.xml.namespace.NamespaceContext; - -/** - * Allow to work with XML name contexts - * - * @author Yuriy Movchan Date: 04/24/2014 - */ -public class SimpleNamespaceContext implements NamespaceContext { - - private final Map prefMap = new HashMap(); - - public SimpleNamespaceContext(final Map prefMap) { - prefMap.putAll(prefMap); - } - - public String getNamespaceURI(String prefix) { - return prefMap.get(prefix); - } - - public String getPrefix(String uri) { - throw new UnsupportedOperationException(); - } - - public Iterator getPrefixes(String uri) { - throw new UnsupportedOperationException(); - } - -} diff --git a/persistence-annotation/pom.xml b/persistence-annotation/pom.xml deleted file mode 100644 index 4e2d00a74..000000000 --- a/persistence-annotation/pom.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - 4.0.0 - oxcore-persistence-annotation - jar - persistence-annotation - - - org.gluu - oxcore - 4.0.0-SNAPSHOT - - - \ No newline at end of file diff --git a/persistence-annotation/src/main/java/org/gluu/persist/annotation/AttributeEnum.java b/persistence-annotation/src/main/java/org/gluu/persist/annotation/AttributeEnum.java deleted file mode 100644 index 12ae84e0d..000000000 --- a/persistence-annotation/src/main/java/org/gluu/persist/annotation/AttributeEnum.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.annotation; - -/** - * Base interface for Persistance enumerations - * - * @author Yuriy Movchan Date: 10.07.2010 - */ -public interface AttributeEnum { - - String getValue(); - - Enum resolveByValue(String value); - -} diff --git a/persistence-annotation/src/main/java/org/gluu/persist/annotation/AttributeName.java b/persistence-annotation/src/main/java/org/gluu/persist/annotation/AttributeName.java deleted file mode 100644 index d2ff245ef..000000000 --- a/persistence-annotation/src/main/java/org/gluu/persist/annotation/AttributeName.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Persistance Attribute - * - * @author Yuriy Movchan Date: 10.07.2010 - */ -@Target({ ElementType.FIELD }) -@Retention(RetentionPolicy.RUNTIME) -public @interface AttributeName { - - /** - * (Optional) The name of the Persistance attribute. Defaults to the field name. - */ - String name() default ""; - - /** - * (Optional) Specify that we ignore this Persistance attribute during read. - * Defaults value is false. - */ - boolean ignoreDuringRead() default false; - - /** - * (Optional) Specify that we ignore this Persistance attribute during update. - * Defaults value is false. - */ - boolean ignoreDuringUpdate() default false; - - /** - * (Optional) Specify that we will only update this attribute, and never - * remove it (set to null). Use this with health status attributes. - */ - boolean updateOnly() default false; - - /** - * (Optional) Specify that search request should wait for indexes update - * Defaults value is false. - */ - boolean consistency() default false; - - /** - * (Optional) Specify whether attribute contains expiration date (E.g. used by Couchbase TTL). - */ - boolean expiry () default false; - -} diff --git a/persistence-annotation/src/main/java/org/gluu/persist/annotation/AttributesList.java b/persistence-annotation/src/main/java/org/gluu/persist/annotation/AttributesList.java deleted file mode 100644 index 3e5e3578e..000000000 --- a/persistence-annotation/src/main/java/org/gluu/persist/annotation/AttributesList.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Persistance Attributes List - * - * @author Yuriy Movchan Date: 10.07.2010 - */ -@Target({ ElementType.FIELD }) -@Retention(RetentionPolicy.RUNTIME) -public @interface AttributesList { - - /** - * (Required) The class property name which contains Persistance attribute name. - */ - String name(); - - /** - * (Required) The class property name which contains Persistance attribute value. - */ - String value(); - - /** - * (Optional) The class property name which contains Persistance attribute value. - */ - String multiValued() default ""; - - /** - * (Optional) Holds additional configuration for Persistance attributes. Defaults - * value not provides additional configuration. - */ - AttributeName[] attributesConfiguration() default {}; - - /** - * (Optional) Specify if attributes should be sorted by property name value. - */ - boolean sortByName() default false; - -} diff --git a/persistence-annotation/src/main/java/org/gluu/persist/annotation/CustomObjectClass.java b/persistence-annotation/src/main/java/org/gluu/persist/annotation/CustomObjectClass.java deleted file mode 100644 index c88980b20..000000000 --- a/persistence-annotation/src/main/java/org/gluu/persist/annotation/CustomObjectClass.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Persistance Object Class - * - * @author Yuriy Movchan Date: 10.21.2010 - */ -@Target({ ElementType.FIELD }) -@Retention(RetentionPolicy.RUNTIME) -public @interface CustomObjectClass { -} diff --git a/persistence-annotation/src/main/java/org/gluu/persist/annotation/DN.java b/persistence-annotation/src/main/java/org/gluu/persist/annotation/DN.java deleted file mode 100644 index ef0f42a9a..000000000 --- a/persistence-annotation/src/main/java/org/gluu/persist/annotation/DN.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.annotation; - -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -import static java.lang.annotation.ElementType.FIELD; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * Persistance DN - * - * @author Yuriy Movchan Date: 10.07.2010 - */ -@Target({ FIELD }) -@Retention(RUNTIME) -public @interface DN { -} diff --git a/persistence-annotation/src/main/java/org/gluu/persist/annotation/DataEntry.java b/persistence-annotation/src/main/java/org/gluu/persist/annotation/DataEntry.java deleted file mode 100644 index b7d0cef21..000000000 --- a/persistence-annotation/src/main/java/org/gluu/persist/annotation/DataEntry.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Mark POJO class as Persistance entry - * - * @author Yuriy Movchan Date: 10.07.2010 - */ -@Target({ ElementType.TYPE }) -@Retention(RetentionPolicy.RUNTIME) -public @interface DataEntry { - - /** - * (Optional) Specify that this entry contains schema definition. - */ - boolean schemaDefinition() default false; - - /** - * (Optional) Specify sortBy properties to sort by default list of Entries. - */ - String[] sortBy() default {}; - -} diff --git a/persistence-annotation/src/main/java/org/gluu/persist/annotation/JsonObject.java b/persistence-annotation/src/main/java/org/gluu/persist/annotation/JsonObject.java deleted file mode 100644 index 9b5c1173d..000000000 --- a/persistence-annotation/src/main/java/org/gluu/persist/annotation/JsonObject.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Persistance Json Object - * - * @author Yuriy Movchan Date: 01/31/2014 - */ -@Target({ ElementType.FIELD }) -@Retention(RetentionPolicy.RUNTIME) -public @interface JsonObject { -} diff --git a/persistence-annotation/src/main/java/org/gluu/persist/annotation/ObjectClass.java b/persistence-annotation/src/main/java/org/gluu/persist/annotation/ObjectClass.java deleted file mode 100644 index 19ab786e6..000000000 --- a/persistence-annotation/src/main/java/org/gluu/persist/annotation/ObjectClass.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Persistance Object Class - * - * @author Yuriy Movchan Date: 10.07.2010 - */ -@Target({ ElementType.TYPE }) -@Retention(RetentionPolicy.RUNTIME) -public @interface ObjectClass { - - @Deprecated // TODO: Remove it in 4.0 - String[] values() default {}; - - String value() default ""; -} diff --git a/persistence-annotation/src/main/java/org/gluu/persist/annotation/Password.java b/persistence-annotation/src/main/java/org/gluu/persist/annotation/Password.java deleted file mode 100644 index 20f581f70..000000000 --- a/persistence-annotation/src/main/java/org/gluu/persist/annotation/Password.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Mark that attribute contains password - * - * @author Yuriy Movchan Date: 05/15/2018 - */ -@Target({ ElementType.FIELD }) -@Retention(RetentionPolicy.RUNTIME) -public @interface Password { -} diff --git a/persistence-annotation/src/main/java/org/gluu/persist/annotation/SchemaEntry.java b/persistence-annotation/src/main/java/org/gluu/persist/annotation/SchemaEntry.java deleted file mode 100644 index 7ef04de87..000000000 --- a/persistence-annotation/src/main/java/org/gluu/persist/annotation/SchemaEntry.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Mark POJO class as Persistance schema entry - * - * @author Yuriy Movchan Date: 10.07.2010 - */ -@Target({ ElementType.TYPE }) -@Retention(RetentionPolicy.RUNTIME) -public @interface SchemaEntry { -} diff --git a/persistence-cdi/src/main/java/org/gluu/persist/service/PersistanceFactoryService.java b/persistence-cdi/src/main/java/org/gluu/persist/service/PersistanceFactoryService.java deleted file mode 100644 index 9aa51f2ea..000000000 --- a/persistence-cdi/src/main/java/org/gluu/persist/service/PersistanceFactoryService.java +++ /dev/null @@ -1,233 +0,0 @@ -package org.gluu.persist.service; - -import java.io.File; -import java.util.Iterator; -import java.util.Map; - -import javax.enterprise.context.ApplicationScoped; -import javax.enterprise.inject.Instance; -import javax.inject.Inject; - -import org.apache.commons.configuration.PropertiesConfiguration; -import org.gluu.persist.PersistenceEntryManagerFactory; -import org.gluu.persist.ldap.impl.LdapEntryManagerFactory; -import org.gluu.persist.model.PersistenceConfiguration; -import org.gluu.util.StringHelper; -import org.gluu.util.properties.FileConfiguration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Factory which creates Persistence Entry Manager - * - * @author Yuriy Movchan Date: 05/10/2019 - */ -@ApplicationScoped -public class PersistanceFactoryService implements BaseFactoryService { - - static { - if (System.getProperty("gluu.base") != null) { - BASE_DIR = System.getProperty("gluu.base"); - } else if ((System.getProperty("catalina.base") != null) && (System.getProperty("catalina.base.ignore") == null)) { - BASE_DIR = System.getProperty("catalina.base"); - } else if (System.getProperty("catalina.home") != null) { - BASE_DIR = System.getProperty("catalina.home"); - } else if (System.getProperty("jboss.home.dir") != null) { - BASE_DIR = System.getProperty("jboss.home.dir"); - } else { - BASE_DIR = null; - } - } - - public static final String BASE_DIR; - public static final String DIR = BASE_DIR + File.separator + "conf" + File.separator; - private static final String GLUU_FILE_PATH = DIR + "gluu.properties"; - - @Inject - private Logger log; - - @Inject - private Instance persistenceEntryManagerFactoryInstance; - - @Override - public PersistenceConfiguration loadPersistenceConfiguration() { - return loadPersistenceConfiguration(null); - } - - @Override - public PersistenceConfiguration loadPersistenceConfiguration(String applicationPropertiesFile) { - PersistenceConfiguration currentPersistenceConfiguration = null; - - String gluuFileName = determineGluuConfigurationFileName(applicationPropertiesFile); - if (gluuFileName != null) { - currentPersistenceConfiguration = createPersistenceConfiguration(gluuFileName); - } - - // Fall back to old LDAP persistence layer - if (currentPersistenceConfiguration == null) { - getLog().warn("Failed to load persistence configuration. Attempting to use LDAP layer"); - PersistenceEntryManagerFactory defaultEntryManagerFactory = getPersistenceEntryManagerFactory(LdapEntryManagerFactory.class); - currentPersistenceConfiguration = createPersistenceConfiguration(defaultEntryManagerFactory.getPersistenceType(), LdapEntryManagerFactory.class, - defaultEntryManagerFactory.getConfigurationFileNames()); - } - - return currentPersistenceConfiguration; - } - - private PersistenceConfiguration createPersistenceConfiguration(String gluuFileName) { - try { - // Determine persistence type - FileConfiguration gluuFileConf = new FileConfiguration(gluuFileName); - if (!gluuFileConf.isLoaded()) { - getLog().error("Unable to load configuration file '{}'", gluuFileName); - return null; - } - - String persistenceType = gluuFileConf.getString("persistence.type"); - PersistenceEntryManagerFactory persistenceEntryManagerFactory = getPersistenceEntryManagerFactory(persistenceType); - if (persistenceEntryManagerFactory == null) { - getLog().error("Unable to get Persistence Entry Manager Factory by type '{}'", persistenceType); - return null; - } - - // Determine configuration file name and factory class type - Class persistenceEntryManagerFactoryType = (Class) persistenceEntryManagerFactory.getClass(); - if (PersistenceEntryManagerFactory.class.isAssignableFrom(persistenceEntryManagerFactoryType.getSuperclass())) { - persistenceEntryManagerFactoryType = (Class) persistenceEntryManagerFactoryType.getSuperclass(); - } - Map persistenceFileNames = persistenceEntryManagerFactory.getConfigurationFileNames(); - - PersistenceConfiguration persistenceConfiguration = createPersistenceConfiguration(persistenceType, persistenceEntryManagerFactoryType, - persistenceFileNames); - - return persistenceConfiguration; - } catch (Exception e) { - getLog().error(e.getMessage(), e); - } - - return null; - } - - private PersistenceConfiguration createPersistenceConfiguration(String persistenceType, Class persistenceEntryManagerFactoryType, - Map persistenceFileNames) { - if (persistenceFileNames == null) { - getLog().error("Unable to get Persistence Entry Manager Factory by type '{}'", persistenceType); - return null; - } - - PropertiesConfiguration mergedPropertiesConfiguration = new PropertiesConfiguration(); - long mergedPersistenceFileLastModifiedTime = -1; - StringBuilder mergedPersistenceFileName = new StringBuilder(); - - for (String prefix : persistenceFileNames.keySet()) { - String persistenceFileName = persistenceFileNames.get(prefix); - - // Build merged file name - if (mergedPersistenceFileName.length() > 0) { - mergedPersistenceFileName.append("!"); - } - mergedPersistenceFileName.append(persistenceFileName); - - // Find last changed file modification time - String persistenceFileNamePath = DIR + persistenceFileName; - File persistenceFile = new File(persistenceFileNamePath); - if (!persistenceFile.exists()) { - getLog().error("Unable to load configuration file '{}'", persistenceFileNamePath); - return null; - } - mergedPersistenceFileLastModifiedTime = Math.max(mergedPersistenceFileLastModifiedTime, persistenceFile.lastModified()); - - // Load persistence configuration - FileConfiguration persistenceFileConf = new FileConfiguration(persistenceFileNamePath); - if (!persistenceFileConf.isLoaded()) { - getLog().error("Unable to load configuration file '{}'", persistenceFileNamePath); - return null; - } - PropertiesConfiguration propertiesConfiguration = persistenceFileConf.getPropertiesConfiguration(); - - // Allow to override value via environment variables - replaceWithSystemValues(propertiesConfiguration); - - // Merge all configuration into one with prefix - appendPropertiesWithPrefix(mergedPropertiesConfiguration, propertiesConfiguration, prefix); - } - - FileConfiguration mergedFileConfiguration = new FileConfiguration(mergedPersistenceFileName.toString(), mergedPropertiesConfiguration); - - PersistenceConfiguration persistenceConfiguration = new PersistenceConfiguration(mergedPersistenceFileName.toString(), mergedFileConfiguration, - persistenceEntryManagerFactoryType, mergedPersistenceFileLastModifiedTime); - - return persistenceConfiguration; - } - - private void replaceWithSystemValues(PropertiesConfiguration propertiesConfiguration) { - Iterator keys = propertiesConfiguration.getKeys(); - while (keys.hasNext()) { - String key = (String) keys.next(); - if (System.getenv(key) != null) { - propertiesConfiguration.setProperty(key, System.getenv(key)); - } - } - } - - private void appendPropertiesWithPrefix(PropertiesConfiguration mergedConfiguration, PropertiesConfiguration appendConfiguration, String prefix) { - Iterator keys = appendConfiguration.getKeys(); - while (keys.hasNext()) { - String key = (String) keys.next(); - Object value = appendConfiguration.getProperty(key); - mergedConfiguration.setProperty(prefix + "." + key, value); - } - } - - private String determineGluuConfigurationFileName(String applicationPropertiesFile) { - String applicationFilePath = DIR + applicationPropertiesFile; - File applicationFile = new File(applicationFilePath); - if (applicationFile.exists()) { - return applicationFilePath; - } - - File ldapFile = new File(GLUU_FILE_PATH); - if (ldapFile.exists()) { - return GLUU_FILE_PATH; - } - - return null; - } - - @Override - public PersistenceEntryManagerFactory getPersistenceEntryManagerFactory(PersistenceConfiguration persistenceConfiguration) { - return getPersistenceEntryManagerFactory(persistenceConfiguration.getEntryManagerFactoryType()); - } - - @Override - public PersistenceEntryManagerFactory getPersistenceEntryManagerFactory(Class persistenceEntryManagerFactoryClass) { - PersistenceEntryManagerFactory persistenceEntryManagerFactory = persistenceEntryManagerFactoryInstance - .select(persistenceEntryManagerFactoryClass).get(); - - return persistenceEntryManagerFactory; - } - - @Override - public PersistenceEntryManagerFactory getPersistenceEntryManagerFactory(String persistenceType) { - // Get persistence entry manager factory - for (PersistenceEntryManagerFactory currentPersistenceEntryManagerFactory : persistenceEntryManagerFactoryInstance) { - log.debug("Found Persistence Entry Manager Factory with type '{}'", currentPersistenceEntryManagerFactory); - if (StringHelper.equalsIgnoreCase(currentPersistenceEntryManagerFactory.getPersistenceType(), persistenceType)) { - return currentPersistenceEntryManagerFactory; - } - } - - return null; - } - - @Override - public Logger getLog() { - if (this.log == null) { - this.log = LoggerFactory.getLogger(PersistanceFactoryService.class); - } - - return this.log; - - } - -} diff --git a/persistence-cdi/src/test/java/org/gluu/persist/service/test/.gitignore b/persistence-cdi/src/test/java/org/gluu/persist/service/test/.gitignore deleted file mode 100644 index eabb0d0d1..000000000 --- a/persistence-cdi/src/test/java/org/gluu/persist/service/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/manual/ diff --git a/persistence-core/docs/LDAP to Couchbase data mapping.png b/persistence-core/docs/LDAP to Couchbase data mapping.png deleted file mode 100644 index ac923958b..000000000 Binary files a/persistence-core/docs/LDAP to Couchbase data mapping.png and /dev/null differ diff --git a/persistence-core/docs/Persistent layer design.png b/persistence-core/docs/Persistent layer design.png deleted file mode 100644 index 4fdaded54..000000000 Binary files a/persistence-core/docs/Persistent layer design.png and /dev/null differ diff --git a/persistence-core/docs/src/LDAP to Couchbase data mapping.dia b/persistence-core/docs/src/LDAP to Couchbase data mapping.dia deleted file mode 100644 index b5f98b003..000000000 Binary files a/persistence-core/docs/src/LDAP to Couchbase data mapping.dia and /dev/null differ diff --git a/persistence-core/docs/src/ldap_tree.png b/persistence-core/docs/src/ldap_tree.png deleted file mode 100644 index e9b989491..000000000 Binary files a/persistence-core/docs/src/ldap_tree.png and /dev/null differ diff --git a/persistence-core/pom.xml b/persistence-core/pom.xml deleted file mode 100644 index 5441710c6..000000000 --- a/persistence-core/pom.xml +++ /dev/null @@ -1,68 +0,0 @@ - - - 4.0.0 - oxcore-persistence-core - jar - persistence-core - - - org.gluu - oxcore - 4.0.0-SNAPSHOT - - - - - - src/main/resources - - **/*.json - **/*.xml - **/*.yml - **/*.properties - - - - - - src/test/resources - - **/*.json - **/*.xml - **/*.yml - **/*.properties - - - - - - - - ${project.groupId} - oxcore-util - ${project.version} - - - ${project.groupId} - oxcore-persistence-filter - ${project.version} - - - ${project.groupId} - oxcore-persistence-model - ${project.version} - - - org.gluu - oxcore-persistence-annotation - ${project.version} - - - - - org.testng - testng - - - - \ No newline at end of file diff --git a/persistence-core/src/main/java/org/gluu/persist/PersistenceEntryManager.java b/persistence-core/src/main/java/org/gluu/persist/PersistenceEntryManager.java deleted file mode 100644 index 6fa162a52..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/PersistenceEntryManager.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2018, Gluu - */ - -package org.gluu.persist; - -import java.util.Date; -import java.util.List; -import java.util.Map; - -import javax.persistence.EntityManager; -import javax.persistence.EntityTransaction; -import javax.persistence.FlushModeType; -import javax.persistence.LockModeType; -import javax.persistence.Query; - -import org.gluu.persist.event.DeleteNotifier; -import org.gluu.persist.exception.operation.DeleteException; -import org.gluu.persist.key.impl.KeyShortcuter; -import org.gluu.persist.model.AttributeData; -import org.gluu.persist.model.BatchOperation; -import org.gluu.persist.model.PagedResult; -import org.gluu.persist.model.SearchScope; -import org.gluu.persist.model.SortOrder; -import org.gluu.persist.operation.PersistenceOperationService; -import org.gluu.search.filter.Filter; -import org.gluu.util.ArrayHelper; - -/** - * Methods which Entry Manager must provide - * - * @author Yuriy Movchan Date: 01/29/2018 - */ -public interface PersistenceEntryManager extends EntityManager { - - boolean authenticate(String primaryKey, String password); - boolean authenticate(String primaryKey, String userName, String password); - - void persist(Object entry); - - T merge(T entry); - - @Deprecated - boolean contains(Object entity); - - boolean contains(String primaryKey, Class entryClass); - boolean contains(String primaryKey, Class entryClass, Filter filter); - - int countEntries(Object entry); - - int countEntries(String primaryKey, Class entryClass, Filter filter); - int countEntries(String primaryKey, Class entryClass, Filter filter, SearchScope scope); - - List createEntities(Class entryClass, Map> entriesAttributes); - - T find(Object primaryKey, Class entryClass, String[] ldapReturnAttributes); - - /** - * Search by sample - * - * @param entry Sample - * @return Result entries - */ - List findEntries(Object entry); - List findEntries(Object entry, int count); - - List findEntries(String primaryKey, Class entryClass, Filter filter); - List findEntries(String primaryKey, Class entryClass, Filter filter, int count); - List findEntries(String primaryKey, Class entryClass, Filter filter, String[] ldapReturnAttributes); - List findEntries(String primaryKey, Class entryClass, Filter filter, String[] ldapReturnAttributes, int count); - List findEntries(String primaryKey, Class entryClass, Filter filter, SearchScope scope, String[] ldapReturnAttributes, - int start, int count, int chunkSize); - List findEntries(String primaryKey, Class entryClass, Filter filter, SearchScope scope, String[] ldapReturnAttributes, - BatchOperation batchOperation, int start, int count, int chunkSize); - - // TODO: Combine sortBy and SortOrder into Sort - PagedResult findPagedEntries(String primaryKey, Class entryClass, Filter filter, String[] ldapReturnAttributes, String sortBy, - SortOrder sortOrder, int start, int count, int chunkSize); - - void remove(Object entry); - void remove(String dn); - int remove(String dn, Class entryClass, Filter filter, int count); - void removeRecursively(String primaryKey); - - boolean hasBranchesSupport(String primaryKey); - String getPersistenceType(String primaryKey); - - Date decodeTime(String primaryKey, String date); - String encodeTime(String primaryKey, Date date); - - int getHashCode(Object entry); - - String[] getObjectClasses(Object entry, Class entryClass); - - Map> groupListByProperties(Class entryClass, List entries, boolean caseSensetive, String groupByProperties, - String sumByProperties); - - void addDeleteSubscriber(DeleteNotifier subscriber); - void removeDeleteSubscriber(DeleteNotifier subscriber); - - void sortListByProperties(Class entryClass, List entries, boolean caseSensetive, String... sortByProperties); - - List exportEntry(String dn); - - void importEntry(String dn, List data); - - PersistenceOperationService getOperationService(); - - boolean destroy(); - - default void clear() { - throw new UnsupportedOperationException("Method not implemented."); - } - - default void close() { - throw new UnsupportedOperationException("Method not implemented."); - } - - default Query createNamedQuery(String name) { - throw new UnsupportedOperationException("Method not implemented."); - } - - default Query createNativeQuery(String sqlString) { - throw new UnsupportedOperationException("Method not implemented."); - } - - default Query createNativeQuery(String sqlString, @SuppressWarnings("rawtypes") Class resultClass) { - throw new UnsupportedOperationException("Method not implemented."); - } - - default Query createNativeQuery(String sqlString, String resultSetMapping) { - throw new UnsupportedOperationException("Method not implemented."); - } - - default Query createQuery(String qlString) { - throw new UnsupportedOperationException("Method not implemented."); - } - - default void flush() { - throw new UnsupportedOperationException("Method not implemented."); - } - - default Object getDelegate() { - throw new UnsupportedOperationException("Method not implemented."); - } - - default FlushModeType getFlushMode() { - throw new UnsupportedOperationException("Method not implemented."); - } - - default T getReference(Class entryClass, Object primaryKey) { - throw new UnsupportedOperationException("Method not implemented."); - } - - default EntityTransaction getTransaction() { - throw new UnsupportedOperationException("Method not implemented."); - } - - default boolean isOpen() { - throw new UnsupportedOperationException("Method not implemented."); - } - - default void joinTransaction() { - throw new UnsupportedOperationException("Method not implemented."); - } - - default void lock(Object entry, LockModeType lockMode) { - throw new UnsupportedOperationException("Method not implemented."); - } - - default void refresh(Object entry) { - throw new UnsupportedOperationException("Method not implemented."); - } - - default void setFlushMode(FlushModeType flushMode) { - throw new UnsupportedOperationException("Method not implemented."); - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/PersistenceEntryManagerFactory.java b/persistence-core/src/main/java/org/gluu/persist/PersistenceEntryManagerFactory.java deleted file mode 100644 index 145608149..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/PersistenceEntryManagerFactory.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2018, Gluu - */ - -package org.gluu.persist; - -import java.util.Map; -import java.util.Properties; - -import org.gluu.persist.service.BaseFactoryService; - -/** - * Factory which creates Persistence Entry Manager - * - * @author Yuriy Movchan Date: 02/02/2018 - */ -public interface PersistenceEntryManagerFactory { - - void initStandalone(BaseFactoryService persistanceFactoryService); - - String getPersistenceType(); - - Map getConfigurationFileNames(); - - PersistenceEntryManager createEntryManager(Properties conf); - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/event/DeleteNotifier.java b/persistence-core/src/main/java/org/gluu/persist/event/DeleteNotifier.java deleted file mode 100644 index a98b56795..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/event/DeleteNotifier.java +++ /dev/null @@ -1,15 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.event; - -public interface DeleteNotifier { - - void onBeforeRemove(String dn); - - void onAfterRemove(String dn); - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/exception/AuthenticationException.java b/persistence-core/src/main/java/org/gluu/persist/exception/AuthenticationException.java deleted file mode 100644 index 943b59359..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/exception/AuthenticationException.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.exception; - -/** - * An exception is a result if user don't have required permissions or failed to authenticate him - * - * @author Yuriy Movchan Date: 10.26.2010 - */ -public class AuthenticationException extends EntryPersistenceException { - - private static final long serialVersionUID = -3321766232087075304L; - - public AuthenticationException(Throwable root) { - super(root); - } - - public AuthenticationException(String string, Throwable root) { - super(string, root); - } - - public AuthenticationException(String s) { - super(s); - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/exception/BasePersistenceException.java b/persistence-core/src/main/java/org/gluu/persist/exception/BasePersistenceException.java deleted file mode 100644 index 2e7048a31..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/exception/BasePersistenceException.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.exception; - -/** - * The base {@link Throwable} type for LDAP Mapping. - */ -public class BasePersistenceException extends RuntimeException { - - private static final long serialVersionUID = 1071769232087073304L; - - public BasePersistenceException(Throwable root) { - super(root); - } - - public BasePersistenceException(String string, Throwable root) { - super(string, root); - } - - public BasePersistenceException(String s) { - super(s); - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/exception/EntryDeleteException.java b/persistence-core/src/main/java/org/gluu/persist/exception/EntryDeleteException.java deleted file mode 100644 index 683e170aa..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/exception/EntryDeleteException.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.exception; - -/** - * An exception is a result if LDAP entry defined incorrectly. - * - * @author Yuriy Movchan Date: 2019/08/26 - */ -public class EntryDeleteException extends BasePersistenceException { - - private static final long serialVersionUID = 1321766232087075304L; - - public EntryDeleteException(Throwable root) { - super(root); - } - - public EntryDeleteException(String string, Throwable root) { - super(string, root); - } - - public EntryDeleteException(String s) { - super(s); - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/exception/EntryPersistenceException.java b/persistence-core/src/main/java/org/gluu/persist/exception/EntryPersistenceException.java deleted file mode 100644 index f21a7d90c..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/exception/EntryPersistenceException.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.exception; - -/** - * An exception is a result if LDAP entry defined incorrectly. - * - * @author Yuriy Movchan Date: 10.07.2010 - */ -public class EntryPersistenceException extends BasePersistenceException { - - private static final long serialVersionUID = 1321766232087075304L; - - public EntryPersistenceException(Throwable root) { - super(root); - } - - public EntryPersistenceException(String string, Throwable root) { - super(string, root); - } - - public EntryPersistenceException(String s) { - super(s); - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/exception/InvalidArgumentException.java b/persistence-core/src/main/java/org/gluu/persist/exception/InvalidArgumentException.java deleted file mode 100644 index 818affac1..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/exception/InvalidArgumentException.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.exception; - -/** - * An exception is a result of something wrong in input parameters. - */ -public class InvalidArgumentException extends MappingException { - - private static final long serialVersionUID = -2223352885909511209L; - - public InvalidArgumentException(String msg, Throwable root) { - super(msg, root); - } - - public InvalidArgumentException(Throwable root) { - super(root); - } - - public InvalidArgumentException(String s) { - super(s); - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/exception/KeyConversionException.java b/persistence-core/src/main/java/org/gluu/persist/exception/KeyConversionException.java deleted file mode 100644 index 727cb6f62..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/exception/KeyConversionException.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2018, Gluu - */ - -package org.gluu.persist.exception; - -/** - * Exception thrown when a dn to key conversion problem occurs - * - * @author Yuriy Movchan Date: 30/05/2018 - */ -public class KeyConversionException extends BasePersistenceException { - - private static final long serialVersionUID = -5254637442590218891L; - - public KeyConversionException(String message) { - super(message); - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/exception/MappingException.java b/persistence-core/src/main/java/org/gluu/persist/exception/MappingException.java deleted file mode 100644 index c7f95b17d..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/exception/MappingException.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.exception; - -/** - * An exception is a result of something screwy in the O-R mappings. - */ -public class MappingException extends BasePersistenceException { - - private static final long serialVersionUID = 1113352885909511209L; - - public MappingException(String msg, Throwable root) { - super(msg, root); - } - - public MappingException(Throwable root) { - super(root); - } - - public MappingException(String s) { - super(s); - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/exception/PropertyAccessException.java b/persistence-core/src/main/java/org/gluu/persist/exception/PropertyAccessException.java deleted file mode 100644 index 87f16e90a..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/exception/PropertyAccessException.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.exception; - -import org.gluu.util.StringHelper; - -/** - * A problem occurred accessing a property of an instance of a persistent class - * by reflection. There are a number of possible underlying causes, including - *
    - *
  • failure of a security check - *
  • an exception occurring inside the getter or setter method - *
- */ -public class PropertyAccessException extends MappingException { - - private static final long serialVersionUID = 1076767768405558202L; - - private final Class persistentClass; - private final String propertyName; - private final boolean wasSetter; - - public PropertyAccessException(Throwable root, String s, boolean wasSetter, Class persistentClass, String propertyName) { - super(s, root); - this.persistentClass = persistentClass; - this.wasSetter = wasSetter; - this.propertyName = propertyName; - } - - public Class getPersistentClass() { - return persistentClass; - } - - public String getPropertyName() { - return propertyName; - } - - @Override - public String getMessage() { - return super.getMessage() + (wasSetter ? " setter of " : " getter of ") - + StringHelper.qualify(persistentClass.getName(), propertyName); - } -} diff --git a/persistence-core/src/main/java/org/gluu/persist/exception/PropertyNotFoundException.java b/persistence-core/src/main/java/org/gluu/persist/exception/PropertyNotFoundException.java deleted file mode 100644 index ad3883b4b..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/exception/PropertyNotFoundException.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.exception; - -/** - * Indicates that an expected getter or setter method could not be found on a - * class. - */ -public class PropertyNotFoundException extends MappingException { - - private static final long serialVersionUID = 2351260797243441135L; - - public PropertyNotFoundException(String s) { - super(s); - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/exception/UnsupportedOperationException.java b/persistence-core/src/main/java/org/gluu/persist/exception/UnsupportedOperationException.java deleted file mode 100644 index 37f07af37..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/exception/UnsupportedOperationException.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.exception; - -/** - * An exception is a result if server doesn't support operation. - * - * @author Yuriy Movchan Date: 08.07.2012 - */ -public class UnsupportedOperationException extends BasePersistenceException { - - private static final long serialVersionUID = 2321766232087075304L; - - public UnsupportedOperationException(Throwable root) { - super(root); - } - - public UnsupportedOperationException(String string, Throwable root) { - super(string, root); - } - - public UnsupportedOperationException(String s) { - super(s); - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/exception/operation/ConfigurationException.java b/persistence-core/src/main/java/org/gluu/persist/exception/operation/ConfigurationException.java deleted file mode 100644 index 8797c4cd2..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/exception/operation/ConfigurationException.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.exception.operation; - -/** - * Configuration exception - * - * @author Yuriy Movchan - * @version 0.1, 05/16/2013 - */ -public class ConfigurationException extends RuntimeException { - - private static final long serialVersionUID = -7590161991536595499L; - - public ConfigurationException() { - } - - public ConfigurationException(String message) { - super(message); - } - - public ConfigurationException(Throwable cause) { - super(cause); - } - - public ConfigurationException(String message, Throwable cause) { - super(message, cause); - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/exception/operation/ConnectionException.java b/persistence-core/src/main/java/org/gluu/persist/exception/operation/ConnectionException.java deleted file mode 100644 index 5893302cb..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/exception/operation/ConnectionException.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.exception.operation; - -/** - * Configuration exception - * - * @author Yuriy Movchan - * @version 0.1, 05/16/2013 - */ -public class ConnectionException extends RuntimeException { - - private static final long serialVersionUID = -7590161991536595499L; - - public ConnectionException() { - } - - public ConnectionException(String message) { - super(message); - } - - public ConnectionException(Throwable cause) { - super(cause); - } - - public ConnectionException(String message, Throwable cause) { - super(message, cause); - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/exception/operation/DeleteException.java b/persistence-core/src/main/java/org/gluu/persist/exception/operation/DeleteException.java deleted file mode 100644 index 65b5df848..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/exception/operation/DeleteException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.exception.operation; - -/** - * Exception thrown when a delte problem occurs - * - * @author Yuriy Movchan Date: 2019/08/26 - */ -public class DeleteException extends PersistenceException { - - private static final long serialVersionUID = 5017957214447362606L; - - public DeleteException(String message, Throwable ex, int errorCode) { - super(message, ex, errorCode); - } - - public DeleteException(String message, int errorCode) { - super(message, errorCode); - } - - public DeleteException(String message) { - super(message); - } - - public DeleteException(String message, Throwable ex) { - super(message, ex); - } - - public DeleteException(Throwable ex, int errorCode) { - super(ex, errorCode); - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/exception/operation/DuplicateEntryException.java b/persistence-core/src/main/java/org/gluu/persist/exception/operation/DuplicateEntryException.java deleted file mode 100644 index fa3e77ca5..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/exception/operation/DuplicateEntryException.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.exception.operation; - -/** - * Duplicate LDAP entry exception - * - * @author Pankaj - */ -public class DuplicateEntryException extends PersistenceException { - /** - * Serialization ID - */ - private static final long serialVersionUID = 6749290172742578916L; - - /** - * Default constructor - */ - public DuplicateEntryException() { - super("Entry already exists"); - } - - /** - * Constructor for returning the offending DN - * - * @param dn - * DN that returned a duplicate - */ - public DuplicateEntryException(final String dn) { - super("Entry already exists: " + dn); - } -} diff --git a/persistence-core/src/main/java/org/gluu/persist/exception/operation/EntryNotFoundException.java b/persistence-core/src/main/java/org/gluu/persist/exception/operation/EntryNotFoundException.java deleted file mode 100644 index 6bd13afa2..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/exception/operation/EntryNotFoundException.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.exception.operation; - -/** - * Exception thrown when a there is no entry - * - * @author Yuriy Movchan Date: 2017/12/29 - */ -public class EntryNotFoundException extends PersistenceException { - - private static final long serialVersionUID = 5017957214447362606L; - - private int resultCode; - - public EntryNotFoundException(String message, Throwable ex, int resultCode) { - super(message, ex); - this.resultCode = resultCode; - } - - public EntryNotFoundException(String message, int resultCode) { - super(message); - this.resultCode = resultCode; - } - - public EntryNotFoundException(String message) { - super(message); - } - - public EntryNotFoundException(String message, Throwable ex) { - super(message, ex); - } - - public EntryNotFoundException(Throwable ex, int resultCode) { - super(ex); - this.resultCode = resultCode; - } - - public final int getResultCode() { - return resultCode; - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/exception/operation/PersistenceException.java b/persistence-core/src/main/java/org/gluu/persist/exception/operation/PersistenceException.java deleted file mode 100644 index f64c358db..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/exception/operation/PersistenceException.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.exception.operation; - -/** - * Generic operation layer exception - * - * @author Yuriy Movchan Date: 29/01/2018 - */ -public class PersistenceException extends Exception { - - /** - * S Serialization ID - */ - private static final long serialVersionUID = 1518677859552078437L; - - /** - * LDAP error code - */ - private int errorCode = 0; - - /** - * Constructor with wrapped exception - * - * @param e - * Wrapped LDAP exception - */ - public PersistenceException(final Throwable e) { - super(e); - } - - public PersistenceException(final Throwable e, final int errorCode) { - super(e); - this.errorCode = errorCode; - } - - /** - * Constructor with detailed error - * - * @param message - * Detailed message - */ - public PersistenceException(final String message) { - super(message); - } - - public PersistenceException(final String message, final int errorCode) { - super(message); - this.errorCode = errorCode; - } - - /** - * Constructor with error and wrapped exception - * - * @param message - * Detailed error - * @param e - * Wrapped LDAP exception - */ - public PersistenceException(final String message, final Throwable e) { - super(message, e); - } - - public PersistenceException(final String message, final Throwable e, final int errorCode) { - super(message, e); - this.errorCode = errorCode; - } - - /** - * Get the LDAP error code - * - * @return The LDAP error code - */ - public int getErrorCode() { - return errorCode; - } - - /** - * Set the LDAP error code - * - * @param code - * Error code - */ - public void setErrorCode(final int code) { - errorCode = code; - } - - /** - * Get the message for display - * - * @return Message for display - */ - @Override - public String toString() { - return getMessage(); - } -} diff --git a/persistence-core/src/main/java/org/gluu/persist/exception/operation/SearchException.java b/persistence-core/src/main/java/org/gluu/persist/exception/operation/SearchException.java deleted file mode 100644 index e75ed1fef..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/exception/operation/SearchException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.exception.operation; - -/** - * Exception thrown when a search problem occurs - * - * @author Yuriy Movchan Date: 2017/12/29 - */ -public class SearchException extends PersistenceException { - - private static final long serialVersionUID = 5017957214447362606L; - - public SearchException(String message, Throwable ex, int errorCode) { - super(message, ex, errorCode); - } - - public SearchException(String message, int errorCode) { - super(message, errorCode); - } - - public SearchException(String message) { - super(message); - } - - public SearchException(String message, Throwable ex) { - super(message, ex); - } - - public SearchException(Throwable ex, int errorCode) { - super(ex, errorCode); - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/exception/operation/SearchScopeException.java b/persistence-core/src/main/java/org/gluu/persist/exception/operation/SearchScopeException.java deleted file mode 100644 index 7a7675f2e..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/exception/operation/SearchScopeException.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.exception.operation; - -/** - * Exception thrown when a search scope problem occurs - * - * @author Yuriy Movchan Date: 29/01/2018 - */ -public class SearchScopeException extends PersistenceException { - - private static final long serialVersionUID = -4554637442590218891L; - - public SearchScopeException(String message) { - super(message); - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/impl/BaseEntryManager.java b/persistence-core/src/main/java/org/gluu/persist/impl/BaseEntryManager.java deleted file mode 100644 index 44e18503c..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/impl/BaseEntryManager.java +++ /dev/null @@ -1,1972 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.impl; - -import java.io.Serializable; -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.IdentityHashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import org.apache.commons.codec.binary.Base64; -import org.gluu.persist.PersistenceEntryManager; -import org.gluu.persist.annotation.AttributeEnum; -import org.gluu.persist.annotation.AttributeName; -import org.gluu.persist.annotation.AttributesList; -import org.gluu.persist.annotation.CustomObjectClass; -import org.gluu.persist.annotation.DN; -import org.gluu.persist.annotation.DataEntry; -import org.gluu.persist.annotation.JsonObject; -import org.gluu.persist.annotation.ObjectClass; -import org.gluu.persist.annotation.SchemaEntry; -import org.gluu.persist.exception.EntryPersistenceException; -import org.gluu.persist.exception.InvalidArgumentException; -import org.gluu.persist.exception.MappingException; -import org.gluu.persist.model.AttributeData; -import org.gluu.persist.model.AttributeDataModification; -import org.gluu.persist.model.AttributeDataModification.AttributeModificationType; -import org.gluu.persist.model.SearchScope; -import org.gluu.persist.reflect.property.Getter; -import org.gluu.persist.reflect.property.PropertyAnnotation; -import org.gluu.persist.reflect.property.Setter; -import org.gluu.persist.reflect.util.ReflectHelper; -import org.gluu.search.filter.Filter; -import org.gluu.util.ArrayHelper; -import org.gluu.util.StringHelper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fasterxml.jackson.databind.ObjectMapper; - -/** - * Abstract Entry Manager - * - * @author Yuriy Movchan Date: 10.07.2010 - */ -public abstract class BaseEntryManager implements PersistenceEntryManager { - - private static final Logger LOG = LoggerFactory.getLogger(BaseEntryManager.class); - - private static final Class[] LDAP_ENTRY_TYPE_ANNOTATIONS = { DataEntry.class, SchemaEntry.class, - ObjectClass.class }; - private static final Class[] LDAP_ENTRY_PROPERTY_ANNOTATIONS = { AttributeName.class, AttributesList.class, - JsonObject.class }; - private static final Class[] LDAP_CUSTOM_OBJECT_CLASS_PROPERTY_ANNOTATION = { CustomObjectClass.class }; - private static final Class[] LDAP_DN_PROPERTY_ANNOTATION = { DN.class }; - - public static final String OBJECT_CLASS = "objectClass"; - public static final String[] EMPTY_STRING_ARRAY = new String[0]; - - private static final Class[] GROUP_BY_ALLOWED_DATA_TYPES = { String.class, Date.class, Integer.class, - AttributeEnum.class }; - private static final Class[] SUM_BY_ALLOWED_DATA_TYPES = { int.class, Integer.class, float.class, Float.class, - double.class, Double.class }; - - private final Map> classAnnotations = new HashMap>(); - private final Map classGetters = new HashMap(); - private final Map classSetters = new HashMap(); - - private static Object CLASS_ANNOTATIONS_LOCK = new Object(); - private static Object CLASS_SETTERS_LOCK = new Object(); - private static Object CLASS_GETTERS_LOCK = new Object(); - - private static final ObjectMapper JSON_OBJECT_MAPPER = new ObjectMapper(); - - protected static final String[] NO_STRINGS = new String[0]; - protected static final Object[] NO_OBJECTS = new Object[0]; - - protected static final Comparator LINE_LENGHT_COMPARATOR = new LineLenghtComparator(false); - - protected static final int DEFAULT_PAGINATION_SIZE = 100; - - @Override - public void persist(Object entry) { - if (entry == null) { - throw new MappingException("Entry to persist is null"); - } - - // Check entry class - Class entryClass = entry.getClass(); - checkEntryClass(entryClass, false); - List propertiesAnnotations = getEntryPropertyAnnotations(entryClass); - - Object dnValue = getDNValue(entry, entryClass); - - List attributes = getAttributesListForPersist(entry, propertiesAnnotations); - - // Add object classes - String[] objectClasses = getObjectClasses(entry, entryClass); - attributes.add(new AttributeData(OBJECT_CLASS, objectClasses, true)); - - LOG.debug(String.format("LDAP attributes for persist: %s", attributes)); - - persist(dnValue.toString(), attributes); - } - - protected abstract void persist(String dn, List attributes); - - @Override - @SuppressWarnings("unchecked") - public List findEntries(Object entry, int count) { - if (entry == null) { - throw new MappingException("Entry to find is null"); - } - - // Check entry class - Class entryClass = (Class) entry.getClass(); - checkEntryClass(entryClass, false); - List propertiesAnnotations = getEntryPropertyAnnotations(entryClass); - - Object dnValue = getDNValue(entry, entryClass); - - List attributes = getAttributesListForPersist(entry, propertiesAnnotations); - Filter searchFilter = createFilterByEntry(entry, entryClass, attributes); - - return findEntries(dnValue.toString(), entryClass, searchFilter, SearchScope.SUB, null, 0, count, - DEFAULT_PAGINATION_SIZE); - } - - @Override - public List findEntries(Object entry) { - return findEntries(entry, 0); - } - - @Override - public List findEntries(String baseDN, Class entryClass, Filter filter) { - return findEntries(baseDN, entryClass, filter, SearchScope.SUB, null, null, 0, 0, 0); - } - - @Override - public List findEntries(String baseDN, Class entryClass, Filter filter, int count) { - return findEntries(baseDN, entryClass, filter, SearchScope.SUB, null, null, 0, count, 0); - } - - @Override - public List findEntries(String baseDN, Class entryClass, Filter filter, String[] ldapReturnAttributes) { - return findEntries(baseDN, entryClass, filter, SearchScope.SUB, ldapReturnAttributes, null, 0, 0, 0); - } - - @Override - public List findEntries(String baseDN, Class entryClass, Filter filter, String[] ldapReturnAttributes, - int count) { - return findEntries(baseDN, entryClass, filter, SearchScope.SUB, ldapReturnAttributes, null, 0, count, 0); - } - - @Override - public List findEntries(String baseDN, Class entryClass, Filter filter, SearchScope scope, - String[] ldapReturnAttributes, int start, int count, int chunkSize) { - return findEntries(baseDN, entryClass, filter, scope, ldapReturnAttributes, null, start, count, chunkSize); - } - - @SuppressWarnings("unchecked") - public int countEntries(Object entry) { - if (entry == null) { - throw new MappingException("Entry to count is null"); - } - - // Check entry class - Class entryClass = (Class) entry.getClass(); - checkEntryClass(entryClass, false); - List propertiesAnnotations = getEntryPropertyAnnotations(entryClass); - - Object dnValue = getDNValue(entry, entryClass); - - List attributes = getAttributesListForPersist(entry, propertiesAnnotations); - Filter searchFilter = createFilterByEntry(entry, entryClass, attributes); - - return countEntries(dnValue.toString(), entryClass, searchFilter); - } - - @SuppressWarnings("unchecked") - protected T merge(T entry, boolean isSchemaUpdate, AttributeModificationType schemaModificationType) { - if (entry == null) { - throw new MappingException("Entry to persist is null"); - } - - Class entryClass = entry.getClass(); - checkEntryClass(entryClass, isSchemaUpdate); - List propertiesAnnotations = getEntryPropertyAnnotations(entryClass); - Map propertiesAnnotationsMap = prepareEntryPropertiesTypes(entryClass, propertiesAnnotations); - - Object dnValue = getDNValue(entry, entryClass); - - List attributesToPersist = getAttributesListForPersist(entry, propertiesAnnotations); - Map attributesToPersistMap = getAttributesMap(attributesToPersist); - - // Load entry - List attributesFromLdap; - if (isSchemaUpdate) { - // If it's schema modification request we don't need to load - // attributes from LDAP - attributesFromLdap = new ArrayList(); - } else { - List currentLdapReturnAttributesList = getAttributesList(entry, propertiesAnnotations, false); - currentLdapReturnAttributesList.add("objectClass"); - - attributesFromLdap = find(dnValue.toString(), propertiesAnnotationsMap, currentLdapReturnAttributesList.toArray(EMPTY_STRING_ARRAY)); - } - Map attributesFromLdapMap = getAttributesMap(attributesFromLdap); - - // Prepare list of modifications - - // Process properties with Attribute annotation - List attributeDataModifications = collectAttributeModifications( - propertiesAnnotations, attributesToPersistMap, attributesFromLdapMap, isSchemaUpdate, - schemaModificationType); - - updateMergeChanges(dnValue.toString(), entry, isSchemaUpdate, entryClass, attributesFromLdapMap, attributeDataModifications); - - LOG.debug(String.format("LDAP attributes for merge: %s", attributeDataModifications)); - - merge(dnValue.toString(), attributeDataModifications); - - return (T) find(entryClass, dnValue.toString(), null, propertiesAnnotations, propertiesAnnotationsMap); - } - - protected abstract void updateMergeChanges(String baseDn, T entry, boolean isSchemaUpdate, Class entryClass, - Map attributesFromLdapMap, - List attributeDataModifications); - - protected List collectAttributeModifications( - List propertiesAnnotations, Map attributesToPersistMap, - Map attributesFromLdapMap, boolean isSchemaUpdate, - AttributeModificationType schemaModificationType) { - List attributeDataModifications = new ArrayList(); - - for (PropertyAnnotation propertiesAnnotation : propertiesAnnotations) { - String propertyName = propertiesAnnotation.getPropertyName(); - Annotation ldapAttribute; - - ldapAttribute = ReflectHelper.getAnnotationByType(propertiesAnnotation.getAnnotations(), - AttributeName.class); - if (ldapAttribute != null) { - String ldapAttributeName = ((AttributeName) ldapAttribute).name(); - if (StringHelper.isEmpty(ldapAttributeName)) { - ldapAttributeName = propertyName; - } - ldapAttributeName = ldapAttributeName.toLowerCase(); - - AttributeData attributeToPersist = attributesToPersistMap.get(ldapAttributeName); - AttributeData attributeFromLdap = attributesFromLdapMap.get(ldapAttributeName); - - // Remove processed attributes - attributesToPersistMap.remove(ldapAttributeName); - attributesFromLdapMap.remove(ldapAttributeName); - - AttributeName ldapAttributeAnnotation = (AttributeName) ldapAttribute; - if (ldapAttributeAnnotation.ignoreDuringUpdate()) { - continue; - } - - if (attributeFromLdap != null && attributeToPersist != null) { - // Modify DN entry attribute in DS - if (!attributeFromLdap.equals(attributeToPersist)) { - if (isEmptyAttributeValues(attributeToPersist) && !ldapAttributeAnnotation.updateOnly()) { - attributeDataModifications.add(new AttributeDataModification( - AttributeModificationType.REMOVE, null, attributeFromLdap)); - } else { - attributeDataModifications.add(new AttributeDataModification( - AttributeModificationType.REPLACE, attributeToPersist, attributeFromLdap)); - } - } - } else if ((attributeFromLdap == null) && (attributeToPersist != null)) { - // Add entry attribute or change schema - if (isSchemaUpdate && (attributeToPersist.getValue() == null - && Arrays.equals(attributeToPersist.getValues(), new Object[] {}))) { - continue; - } - AttributeModificationType modType = isSchemaUpdate ? schemaModificationType - : AttributeModificationType.ADD; - if (AttributeModificationType.ADD.equals(modType)) { - if (!isEmptyAttributeValues(attributeToPersist)) { - attributeDataModifications.add( - new AttributeDataModification(AttributeModificationType.ADD, attributeToPersist)); - } - } else { - attributeDataModifications.add(new AttributeDataModification(AttributeModificationType.REMOVE, - null, attributeToPersist)); - } - } else if ((attributeFromLdap != null) && (attributeToPersist == null)) { - // Remove if attribute not marked as ignoreDuringRead = true - // or updateOnly = true - if (!ldapAttributeAnnotation.ignoreDuringRead() && !ldapAttributeAnnotation.updateOnly()) { - attributeDataModifications.add(new AttributeDataModification(AttributeModificationType.REMOVE, - null, attributeFromLdap)); - } - } - } - } - - // Process properties with @AttributesList annotation - for (PropertyAnnotation propertiesAnnotation : propertiesAnnotations) { - Annotation ldapAttribute; - ldapAttribute = ReflectHelper.getAnnotationByType(propertiesAnnotation.getAnnotations(), - AttributesList.class); - if (ldapAttribute != null) { - Map ldapAttributesConfiguration = new HashMap(); - for (AttributeName ldapAttributeConfiguration : ((AttributesList) ldapAttribute) - .attributesConfiguration()) { - ldapAttributesConfiguration.put(ldapAttributeConfiguration.name(), ldapAttributeConfiguration); - } - - // Prepare attributes for removal - for (AttributeData attributeFromLdap : attributesFromLdapMap.values()) { - String attributeName = attributeFromLdap.getName(); - if (OBJECT_CLASS.equalsIgnoreCase(attributeName)) { - continue; - } - - AttributeName ldapAttributeConfiguration = ldapAttributesConfiguration.get(attributeName); - if ((ldapAttributeConfiguration != null) && ldapAttributeConfiguration.ignoreDuringUpdate()) { - continue; - } - - if (!attributesToPersistMap.containsKey(attributeName.toLowerCase())) { - // Remove if attribute not marked as ignoreDuringRead = - // true - if ((ldapAttributeConfiguration == null) || ((ldapAttributeConfiguration != null) - && !ldapAttributeConfiguration.ignoreDuringRead())) { - attributeDataModifications.add(new AttributeDataModification( - AttributeModificationType.REMOVE, null, attributeFromLdap)); - } - } - } - - // Prepare attributes for adding and replace - for (AttributeData attributeToPersist : attributesToPersistMap.values()) { - String attributeName = attributeToPersist.getName(); - - AttributeName ldapAttributeConfiguration = ldapAttributesConfiguration.get(attributeName); - if ((ldapAttributeConfiguration != null) && ldapAttributeConfiguration.ignoreDuringUpdate()) { - continue; - } - - AttributeData attributeFromLdap = attributesFromLdapMap.get(attributeName.toLowerCase()); - if (attributeFromLdap == null) { - // Add entry attribute or change schema - AttributeModificationType modType = isSchemaUpdate ? schemaModificationType - : AttributeModificationType.ADD; - if (AttributeModificationType.ADD.equals(modType)) { - if (!isEmptyAttributeValues(attributeToPersist)) { - attributeDataModifications.add(new AttributeDataModification( - AttributeModificationType.ADD, attributeToPersist)); - } - } else { - attributeDataModifications.add(new AttributeDataModification( - AttributeModificationType.REMOVE, null, attributeToPersist)); - } - } else if ((attributeFromLdap != null) - && (Arrays.equals(attributeToPersist.getValues(), new String[] {}))) { - - attributeDataModifications.add(new AttributeDataModification(AttributeModificationType.REMOVE, - null, attributeFromLdap)); - } else { - if (!attributeFromLdap.equals(attributeToPersist)) { - if (isEmptyAttributeValues(attributeToPersist) - && !ldapAttributeConfiguration.updateOnly()) { - attributeDataModifications.add(new AttributeDataModification( - AttributeModificationType.REMOVE, null, attributeFromLdap)); - } else { - attributeDataModifications.add(new AttributeDataModification( - AttributeModificationType.REPLACE, attributeToPersist, attributeFromLdap)); - } - } - } - } - - } - } - - return attributeDataModifications; - } - - protected boolean isEmptyAttributeValues(AttributeData attributeData) { - Object[] attributeToPersistValues = attributeData.getValues(); - - return ArrayHelper.isEmpty(attributeToPersistValues) - || ((attributeToPersistValues.length == 1) && StringHelper.isEmpty(String.valueOf(attributeToPersistValues[0]))); - } - - protected abstract void merge(String dn, List attributeDataModifications); - - public abstract void remove(String dn); - - @Override - public boolean contains(Object entry) { - if (entry == null) { - throw new MappingException("Entry to persist is null"); - } - - // Check entry class - Class entryClass = entry.getClass(); - checkEntryClass(entryClass, false); - String[] objectClasses = getObjectClasses(entry, entryClass); - List propertiesAnnotations = getEntryPropertyAnnotations(entryClass); - - Object dnValue = getDNValue(entry, entryClass); - - List attributes = getAttributesListForPersist(entry, propertiesAnnotations); - - String[] ldapReturnAttributes = getAttributes(null, propertiesAnnotations, false); - - return contains(dnValue.toString(), entryClass, propertiesAnnotations, attributes, objectClasses, ldapReturnAttributes); - } - - protected boolean contains(Class entryClass, String primaryKey, String[] ldapReturnAttributes) { - if (StringHelper.isEmptyString(primaryKey)) { - throw new MappingException("DN to find entry is null"); - } - - checkEntryClass(entryClass, true); - List propertiesAnnotations = getEntryPropertyAnnotations(entryClass); - Map propertiesAnnotationsMap = prepareEntryPropertiesTypes(entryClass, propertiesAnnotations); - - try { - List results = find(primaryKey, propertiesAnnotationsMap, ldapReturnAttributes); - return (results != null) && (results.size() > 0); - } catch (EntryPersistenceException ex) { - return false; - } - } - - @Override - public boolean contains(String baseDN, Class entryClass, Filter filter) { - // Check entry class - checkEntryClass(entryClass, false); - String[] objectClasses = getTypeObjectClasses(entryClass); - List propertiesAnnotations = getEntryPropertyAnnotations(entryClass); - String[] ldapReturnAttributes = getAttributes(null, propertiesAnnotations, false); - - return contains(baseDN, entryClass, propertiesAnnotations, filter, objectClasses, ldapReturnAttributes); - } - - protected boolean contains(String baseDN, Class entryClass, List propertiesAnnotations, List attributes, String[] objectClasses, - String... ldapReturnAttributes) { - Filter[] attributesFilters = createAttributesFilter(attributes); - Filter attributesFilter = null; - if (attributesFilters != null) { - attributesFilter = Filter.createANDFilter(attributesFilters); - } - - return contains(baseDN, entryClass, propertiesAnnotations, attributesFilter, objectClasses, ldapReturnAttributes); - } - - protected abstract boolean contains(String baseDN, Class entryClass, List propertiesAnnotations, - Filter filter, String[] objectClasses, String[] ldapReturnAttributes); - - @Override - public boolean contains(String primaryKey, Class entryClass) { - return contains(entryClass, primaryKey, (String[]) null); - } - - @Override - public T find(Class entryClass, Object primaryKey) { - return find(primaryKey, entryClass, null); - } - - @Override - public T find(Object primaryKey, Class entryClass, String[] ldapReturnAttributes) { - if (StringHelper.isEmptyString(primaryKey)) { - throw new MappingException("DN to find entry is null"); - } - - checkEntryClass(entryClass, true); - List propertiesAnnotations = getEntryPropertyAnnotations(entryClass); - Map propertiesAnnotationsMap = prepareEntryPropertiesTypes(entryClass, propertiesAnnotations); - - return find(entryClass, primaryKey, ldapReturnAttributes, propertiesAnnotations, propertiesAnnotationsMap); - } - - protected String[] getAttributes(T entry, List propertiesAnnotations, - boolean isIgnoreAttributesList) { - List attributes = getAttributesList(entry, propertiesAnnotations, isIgnoreAttributesList); - - if (attributes == null) { - return null; - } - - return attributes.toArray(new String[0]); - } - - protected String[] getAttributes(Map attributesMap) { - if (attributesMap == null) { - return null; - } - return attributesMap.keySet().toArray(new String[0]); - } - - protected List getAttributesList(T entry, List propertiesAnnotations, - boolean isIgnoreAttributesList) { - Map attributesMap = getAttributesMap(entry, propertiesAnnotations, isIgnoreAttributesList); - - if (attributesMap == null) { - return null; - } - - return new ArrayList(attributesMap.keySet()); - } - - protected Map getAttributesMap(T entry, List propertiesAnnotations, - boolean isIgnoreAttributesList) { - Map attributes = new HashMap(); - - for (PropertyAnnotation propertiesAnnotation : propertiesAnnotations) { - String propertyName = propertiesAnnotation.getPropertyName(); - Annotation ldapAttribute; - - if (!isIgnoreAttributesList) { - ldapAttribute = ReflectHelper.getAnnotationByType(propertiesAnnotation.getAnnotations(), - AttributesList.class); - if (ldapAttribute != null) { - if (entry == null) { - return null; - } else { - List attributesList = getAttributesFromAttributesList(entry, - ldapAttribute, propertyName); - for (AttributeData attributeData : attributesList) { - String ldapAttributeName = attributeData.getName(); - if (!attributes.containsKey(ldapAttributeName)) { - attributes.put(ldapAttributeName, propertiesAnnotation); - } - } - } - } - } - - // Process properties with AttributeName annotation - ldapAttribute = ReflectHelper.getAnnotationByType(propertiesAnnotation.getAnnotations(), - AttributeName.class); - if (ldapAttribute != null) { - String ldapAttributeName = ((AttributeName) ldapAttribute).name(); - if (StringHelper.isEmpty(ldapAttributeName)) { - ldapAttributeName = propertyName; - } - - if (!attributes.containsKey(ldapAttributeName)) { - attributes.put(ldapAttributeName, propertiesAnnotation); - } - } - } - - if (attributes.size() == 0) { - return null; - } - - return attributes; - } - - protected Map prepareEntryPropertiesTypes(Class entryClass, List propertiesAnnotations) { - Map propertiesAnnotationsMap = getAttributesMap(null, propertiesAnnotations, true); - if (propertiesAnnotationsMap== null) { - return new HashMap(0); - } - - preparePropertyAnnotationTypes(entryClass, propertiesAnnotationsMap); - - return propertiesAnnotationsMap; - } - - protected void preparePropertyAnnotationTypes(Class entry, Map propertiesAnnotationsMap) { - for (PropertyAnnotation propertiesAnnotation : propertiesAnnotationsMap.values()) { - String propertyName = propertiesAnnotation.getPropertyName(); - - Class parameterType = getSetterPropertyType(entry, propertyName); - propertiesAnnotation.setParameterType(parameterType); - } - } - - private Class getSetterPropertyType(Class entry, String propertyName) { - Setter propertyValueSetter = getSetter(entry, propertyName); - if (propertyValueSetter == null) { - throw new MappingException("Entry should has setter for property " + propertyName); - } - - Class parameterType = ReflectHelper.getSetterType(propertyValueSetter); - return parameterType; - } - - private T find(Class entryClass, Object primaryKey, String[] ldapReturnAttributes, - List propertiesAnnotations, Map propertiesAnnotationsMap) { - Map> entriesAttributes = new HashMap>(); - - String[] currentLdapReturnAttributes = ldapReturnAttributes; - if (ArrayHelper.isEmpty(currentLdapReturnAttributes)) { - currentLdapReturnAttributes = getAttributes(null, propertiesAnnotations, false); - } - - List ldapAttributes = find(primaryKey.toString(), propertiesAnnotationsMap, currentLdapReturnAttributes); - - entriesAttributes.put(String.valueOf(primaryKey), ldapAttributes); - List results = createEntities(entryClass, propertiesAnnotations, entriesAttributes); - return results.get(0); - } - - protected abstract List find(String dn, Map propertiesAnnotationsMap, String... attributes); - - protected boolean checkEntryClass(Class entryClass, boolean isAllowSchemaEntry) { - if (entryClass == null) { - throw new MappingException("Entry class is null"); - } - - // Check if entry is LDAP Entry - List entryAnnotations = ReflectHelper.getClassAnnotations(entryClass, LDAP_ENTRY_TYPE_ANNOTATIONS); - - Annotation ldapSchemaEntry = ReflectHelper.getAnnotationByType(entryAnnotations, SchemaEntry.class); - Annotation ldapEntry = ReflectHelper.getAnnotationByType(entryAnnotations, DataEntry.class); - if (isAllowSchemaEntry) { - if ((ldapSchemaEntry == null) && (ldapEntry == null)) { - throw new MappingException("Entry should has DataEntry or SchemaEntry annotation"); - } - } else { - if (ldapEntry == null) { - throw new MappingException("Entry should has DataEntry annotation"); - } - } - - return true; - } - - protected boolean isSchemaEntry(Class entryClass) { - if (entryClass == null) { - throw new MappingException("Entry class is null"); - } - - // Check if entry is LDAP Entry - List entryAnnotations = ReflectHelper.getClassAnnotations(entryClass, LDAP_ENTRY_TYPE_ANNOTATIONS); - - return ReflectHelper.getAnnotationByType(entryAnnotations, SchemaEntry.class) != null; - } - - protected String[] getEntrySortBy(Class entryClass) { - if (entryClass == null) { - throw new MappingException("Entry class is null"); - } - - // Check if entry is LDAP Entry - List entryAnnotations = ReflectHelper.getClassAnnotations(entryClass, LDAP_ENTRY_TYPE_ANNOTATIONS); - Annotation annotation = ReflectHelper.getAnnotationByType(entryAnnotations, DataEntry.class); - - if (annotation == null) { - return null; - } - - return ((DataEntry) annotation).sortBy(); - } - - @Override - public String[] getObjectClasses(Object entry, Class entryClass) { - String[] typeObjectClasses = getTypeObjectClasses(entryClass); - String[] customObjectClasses = getCustomObjectClasses(entry, entryClass); - - if (ArrayHelper.isEmpty(typeObjectClasses)) { - return customObjectClasses; - } - - String[] mergedArray = ArrayHelper.arrayMerge(typeObjectClasses, customObjectClasses); - Set objecClassSet = new HashSet(); - objecClassSet.addAll(Arrays.asList(mergedArray)); - return objecClassSet.toArray(new String[0]); - } - - protected String[] getTypeObjectClasses(Class entryClass) { - // Check if entry is LDAP Entry - List entryAnnotations = ReflectHelper.getClassAnnotations(entryClass, LDAP_ENTRY_TYPE_ANNOTATIONS); - - // Get object classes - Annotation ldapObjectClass = ReflectHelper.getAnnotationByType(entryAnnotations, ObjectClass.class); - if (ldapObjectClass == null) { - return EMPTY_STRING_ARRAY; - } - - if (StringHelper.isEmpty(((ObjectClass) ldapObjectClass).value())) { - return EMPTY_STRING_ARRAY; - } - - return new String[] { ((ObjectClass) ldapObjectClass).value() }; - } - - protected String[] getCustomObjectClasses(Object entry, Class entryClass) { - List result = new ArrayList(); - List customObjectAnnotations = getEntryCustomObjectClassAnnotations(entryClass); - - for (PropertyAnnotation propertiesAnnotation : customObjectAnnotations) { - String propertyName = propertiesAnnotation.getPropertyName(); - - Getter getter = getGetter(entryClass, propertyName); - if (getter == null) { - throw new MappingException("Entry should has getter for property " + propertyName); - } - - Class parameterType = getSetterPropertyType(entryClass, propertyName); - boolean multiValued = isMultiValued(parameterType); - - AttributeData attribute = getAttributeData(propertyName, propertyName, getter, entry, multiValued, false); - if (attribute != null) { - for (String objectClass : attribute.getStringValues()) { - if (objectClass != null) { - result.add(objectClass); - } - } - } - break; - } - - return result.toArray(new String[0]); - } - - protected void setCustomObjectClasses(Object entry, Class entryClass, String[] objectClasses) { - List customObjectAnnotations = getEntryCustomObjectClassAnnotations(entryClass); - - for (PropertyAnnotation propertiesAnnotation : customObjectAnnotations) { - String propertyName = propertiesAnnotation.getPropertyName(); - - Setter setter = getSetter(entryClass, propertyName); - if (setter == null) { - throw new MappingException("Entry should has setter for property " + propertyName); - } - - AttributeData attribute = new AttributeData(propertyName, objectClasses); - - setPropertyValue(propertyName, setter, entry, attribute, false); - break; - } - } - - protected String getDNPropertyName(Class entryClass) { - List propertiesAnnotations = getEntryDnAnnotations(entryClass); - if (propertiesAnnotations.size() == 0) { - throw new MappingException("Entry should has property with annotation LdapDN"); - } - - if (propertiesAnnotations.size() > 1) { - throw new MappingException("Entry should has only one property with annotation LdapDN"); - } - - return propertiesAnnotations.get(0).getPropertyName(); - } - - protected List createEntities(Class entryClass, List propertiesAnnotations, - Map> entriesAttributes) { - return createEntities(entryClass, propertiesAnnotations, entriesAttributes, true); - } - - protected List createEntities(Class entryClass, List propertiesAnnotations, - Map> entriesAttributes, boolean doSort) { - // Check if entry has DN property - String dnProperty = getDNPropertyName(entryClass); - - // Get DN value - Setter dnSetter = getSetter(entryClass, dnProperty); - if (dnSetter == null) { - throw new MappingException("Entry should has getter for property " + dnProperty); - } - - // Type object classes - String[] typeObjectClasses = getTypeObjectClasses(entryClass); - Arrays.sort(typeObjectClasses); - - List results = new ArrayList(entriesAttributes.size()); - for (Entry> entryAttributes : entriesAttributes.entrySet()) { - String dn = entryAttributes.getKey(); - List attributes = entryAttributes.getValue(); - Map attributesMap = getAttributesMap(attributes); - - T entry; - List customObjectClasses = null; - try { - entry = ReflectHelper.createObjectByDefaultConstructor(entryClass); - } catch (Exception ex) { - throw new MappingException(String.format("Entry %s should has default constructor", entryClass)); - } - results.add(entry); - - dnSetter.set(entry, dn); - - // Remove processed DN attribute - attributesMap.remove(dnProperty); - - // Set loaded properties to entry - - // Process properties with AttributeName annotation - for (PropertyAnnotation propertiesAnnotation : propertiesAnnotations) { - String propertyName = propertiesAnnotation.getPropertyName(); - Annotation ldapAttribute; - - ldapAttribute = ReflectHelper.getAnnotationByType(propertiesAnnotation.getAnnotations(), - AttributeName.class); - if (ldapAttribute != null) { - String ldapAttributeName = ((AttributeName) ldapAttribute).name(); - if (StringHelper.isEmpty(ldapAttributeName)) { - ldapAttributeName = propertyName; - } - ldapAttributeName = ldapAttributeName.toLowerCase(); - - AttributeData attributeData = attributesMap.get(ldapAttributeName); - - // Remove processed attributes - attributesMap.remove(ldapAttributeName); - - if (((AttributeName) ldapAttribute).ignoreDuringRead()) { - continue; - } - - Setter setter = getSetter(entryClass, propertyName); - if (setter == null) { - throw new MappingException("Entry should has setter for property " + propertyName); - } - - Annotation ldapJsonObject = ReflectHelper.getAnnotationByType(propertiesAnnotation.getAnnotations(), - JsonObject.class); - boolean jsonObject = ldapJsonObject != null; - - setPropertyValue(propertyName, setter, entry, attributeData, jsonObject); - } - } - - // Process properties with @AttributesList annotation - for (PropertyAnnotation propertiesAnnotation : propertiesAnnotations) { - String propertyName = propertiesAnnotation.getPropertyName(); - Annotation ldapAttribute; - - ldapAttribute = ReflectHelper.getAnnotationByType(propertiesAnnotation.getAnnotations(), - AttributesList.class); - if (ldapAttribute != null) { - Map ldapAttributesConfiguration = new HashMap(); - for (AttributeName ldapAttributeConfiguration : ((AttributesList) ldapAttribute) - .attributesConfiguration()) { - ldapAttributesConfiguration.put(ldapAttributeConfiguration.name(), ldapAttributeConfiguration); - } - - Setter setter = getSetter(entryClass, propertyName); - if (setter == null) { - throw new MappingException("Entry should has setter for property " + propertyName); - } - - List propertyValue = new ArrayList(); - setter.set(entry, propertyValue); - - Class entryItemType = ReflectHelper.getListType(setter); - if (entryItemType == null) { - throw new MappingException( - "Entry property " + propertyName + " should has setter with specified element type"); - } - - String entryPropertyName = ((AttributesList) ldapAttribute).name(); - Setter entryPropertyNameSetter = getSetter(entryItemType, entryPropertyName); - if (entryPropertyNameSetter == null) { - throw new MappingException( - "Entry should has setter for property " + propertyName + "." + entryPropertyName); - } - - String entryPropertyValue = ((AttributesList) ldapAttribute).value(); - Setter entryPropertyValueSetter = getSetter(entryItemType, entryPropertyValue); - if (entryPropertyValueSetter == null) { - throw new MappingException( - "Entry should has getter for property " + propertyName + "." + entryPropertyValue); - } - - for (AttributeData entryAttribute : attributesMap.values()) { - if (OBJECT_CLASS.equalsIgnoreCase(entryAttribute.getName())) { - String[] objectClasses = entryAttribute.getStringValues(); - if (ArrayHelper.isEmpty(objectClasses)) { - continue; - } - - if (customObjectClasses == null) { - customObjectClasses = new ArrayList(); - } - - for (String objectClass : objectClasses) { - int idx = Arrays.binarySearch(typeObjectClasses, objectClass, new Comparator() { - public int compare(String o1, String o2) { - return o1.toLowerCase().compareTo(o2.toLowerCase()); - } - }); - - if (idx < 0) { - customObjectClasses.add(objectClass); - } - } - - continue; - } - - AttributeName ldapAttributeConfiguration = ldapAttributesConfiguration - .get(entryAttribute.getName()); - if ((ldapAttributeConfiguration != null) && ldapAttributeConfiguration.ignoreDuringRead()) { - continue; - } - - String entryPropertyMultivalued = ((AttributesList) ldapAttribute).multiValued(); - Setter entryPropertyMultivaluedSetter = null; - if (StringHelper.isNotEmpty(entryPropertyMultivalued)) { - entryPropertyMultivaluedSetter = getSetter(entryItemType, entryPropertyMultivalued); - } - if (entryPropertyMultivaluedSetter != null) { - Class parameterType = ReflectHelper.getSetterType(entryPropertyMultivaluedSetter); - if (!parameterType.equals(Boolean.TYPE)) { - throw new MappingException( - "Entry should has getter for property " + propertyName + "." + entryPropertyMultivalued + " with boolean type"); - } - } - - Object listItem = getListItem(propertyName, entryPropertyNameSetter, entryPropertyValueSetter, - entryPropertyMultivaluedSetter, entryItemType, entryAttribute); - if (listItem != null) { - propertyValue.add(listItem); - } - } - - if (doSort) { - sortAttributesListIfNeeded((AttributesList) ldapAttribute, entryItemType, - propertyValue); - } - } - } - - if ((customObjectClasses != null) && (customObjectClasses.size() > 0)) { - setCustomObjectClasses(entry, entryClass, customObjectClasses.toArray(new String[0])); - } - } - - return results; - } - - @Override - public List createEntities(Class entryClass, Map> entriesAttributes) { - checkEntryClass(entryClass, true); - List propertiesAnnotations = getEntryPropertyAnnotations(entryClass); - - return createEntities(entryClass, propertiesAnnotations, entriesAttributes); - } - - @SuppressWarnings("unchecked") - private void sortAttributesListIfNeeded(AttributesList ldapAttribute, Class entryItemType, - List list) { - if (!ldapAttribute.sortByName()) { - return; - } - - sortListByProperties(entryItemType, (List) list, ldapAttribute.name()); - } - - protected void sortEntriesIfNeeded(Class entryClass, List entries) { - String[] sortByProperties = getEntrySortBy(entryClass); - - if (ArrayHelper.isEmpty(sortByProperties)) { - return; - } - - sortListByProperties(entryClass, entries, sortByProperties); - } - - @Override - public void sortListByProperties(Class entryClass, List entries, boolean caseSensetive, - String... sortByProperties) { - // Check input parameters - if (entries == null) { - throw new MappingException("Entries list to sort is null"); - } - - if (entries.size() == 0) { - return; - } - - if ((sortByProperties == null) || (sortByProperties.length == 0)) { - throw new InvalidArgumentException( - "Invalid list of sortBy properties " + Arrays.toString(sortByProperties)); - } - - // Get getters for all properties - Getter[][] propertyGetters = new Getter[sortByProperties.length][]; - for (int i = 0; i < sortByProperties.length; i++) { - String[] tmpProperties = sortByProperties[i].split("\\."); - propertyGetters[i] = new Getter[tmpProperties.length]; - Class currentEntryClass = entryClass; - for (int j = 0; j < tmpProperties.length; j++) { - if (j > 0) { - currentEntryClass = propertyGetters[i][j - 1].getReturnType(); - } - propertyGetters[i][j] = getGetter(currentEntryClass, tmpProperties[j]); - } - - if (propertyGetters[i][tmpProperties.length - 1] == null) { - throw new MappingException("Entry should has getteres for all properties " + sortByProperties[i]); - } - - Class propertyType = propertyGetters[i][tmpProperties.length - 1].getReturnType(); - if (!((propertyType == String.class) || (propertyType == Date.class) || (propertyType == Integer.class) - || (propertyType == Integer.TYPE))) { - throw new MappingException("Entry properties should has String, Date or Integer type. Property: '" - + tmpProperties[tmpProperties.length - 1] + "'"); - } - } - - PropertyComparator comparator = new PropertyComparator(propertyGetters, caseSensetive); - Collections.sort(entries, comparator); - } - - protected void sortListByProperties(Class entryClass, List entries, String... sortByProperties) { - sortListByProperties(entryClass, entries, false, sortByProperties); - } - - @Override - public Map> groupListByProperties(Class entryClass, List entries, boolean caseSensetive, - String groupByProperties, String sumByProperties) { - // Check input parameters - if (entries == null) { - throw new MappingException("Entries list to group is null"); - } - - if (entries.size() == 0) { - return new HashMap>(0); - } - - if (StringHelper.isEmpty(groupByProperties)) { - throw new InvalidArgumentException("List of groupBy properties is null"); - } - - // Get getters for all properties - Getter[] groupPropertyGetters = getEntryPropertyGetters(entryClass, groupByProperties, - GROUP_BY_ALLOWED_DATA_TYPES); - Setter[] groupPropertySetters = getEntryPropertySetters(entryClass, groupByProperties, - GROUP_BY_ALLOWED_DATA_TYPES); - Getter[] sumPropertyGetters = getEntryPropertyGetters(entryClass, sumByProperties, SUM_BY_ALLOWED_DATA_TYPES); - Setter[] sumPropertySetter = getEntryPropertySetters(entryClass, sumByProperties, SUM_BY_ALLOWED_DATA_TYPES); - - return groupListByPropertiesImpl(entryClass, entries, caseSensetive, groupPropertyGetters, groupPropertySetters, - sumPropertyGetters, sumPropertySetter); - } - - private Getter[] getEntryPropertyGetters(Class entryClass, String properties, Class[] allowedTypes) { - if (StringHelper.isEmpty(properties)) { - return null; - } - - String[] tmpProperties = properties.split("\\,"); - Getter[] propertyGetters = new Getter[tmpProperties.length]; - for (int i = 0; i < tmpProperties.length; i++) { - propertyGetters[i] = getGetter(entryClass, tmpProperties[i].trim()); - - if (propertyGetters[i] == null) { - throw new MappingException("Entry should has getter for property " + tmpProperties[i]); - } - - Class returnType = propertyGetters[i].getReturnType(); - boolean found = false; - for (Class clazz : allowedTypes) { - if (ReflectHelper.assignableFrom(returnType, clazz)) { - found = true; - break; - } - } - - if (!found) { - throw new MappingException( - "Entry property getter should has next data types " + Arrays.toString(allowedTypes)); - } - } - - return propertyGetters; - } - - private Setter[] getEntryPropertySetters(Class entryClass, String properties, Class[] allowedTypes) { - if (StringHelper.isEmpty(properties)) { - return null; - } - - String[] tmpProperties = properties.split("\\,"); - Setter[] propertySetters = new Setter[tmpProperties.length]; - for (int i = 0; i < tmpProperties.length; i++) { - propertySetters[i] = getSetter(entryClass, tmpProperties[i].trim()); - - if (propertySetters[i] == null) { - throw new MappingException("Entry should has setter for property " + tmpProperties[i]); - } - - Class paramType = ReflectHelper.getSetterType(propertySetters[i]); - boolean found = false; - for (Class clazz : allowedTypes) { - if (ReflectHelper.assignableFrom(paramType, clazz)) { - found = true; - break; - } - } - - if (!found) { - throw new MappingException( - "Entry property setter should has next data types " + Arrays.toString(allowedTypes)); - } - } - - return propertySetters; - } - - protected Map> groupListByProperties(Class entryClass, List entries, String groupByProperties, - String sumByProperties) { - return groupListByProperties(entryClass, entries, false, groupByProperties, sumByProperties); - } - - private Map> groupListByPropertiesImpl(Class entryClass, List entries, boolean caseSensetive, - Getter[] groupPropertyGetters, Setter[] groupPropertySetters, Getter[] sumProperyGetters, - Setter[] sumPropertySetter) { - Map keys = new HashMap(); - Map> groups = new IdentityHashMap>(); - - for (T entry : entries) { - String key = getEntryKey(entry, caseSensetive, groupPropertyGetters); - - T entryKey = keys.get(key); - if (entryKey == null) { - try { - entryKey = ReflectHelper.createObjectByDefaultConstructor(entryClass); - } catch (Exception ex) { - throw new MappingException(String.format("Entry %s should has default constructor", entryClass), - ex); - } - try { - ReflectHelper.copyObjectPropertyValues(entry, entryKey, groupPropertyGetters, groupPropertySetters); - } catch (Exception ex) { - throw new MappingException("Failed to set values in group Entry", ex); - } - keys.put(key, entryKey); - } - - List groupValues = groups.get(entryKey); - if (groupValues == null) { - groupValues = new ArrayList(); - groups.put(entryKey, groupValues); - } - - try { - if (sumProperyGetters != null) { - ReflectHelper.sumObjectPropertyValues(entryKey, entry, sumProperyGetters, sumPropertySetter); - } - } catch (Exception ex) { - throw new MappingException("Failed to sum values in group Entry", ex); - } - - groupValues.add(entry); - } - - return groups; - } - - private Map getAttributesMap(List attributes) { - Map attributesMap = new HashMap(attributes.size()); - for (AttributeData attribute : attributes) { - attributesMap.put(attribute.getName().toLowerCase(), attribute); - } - - return attributesMap; - } - - private AttributeData getAttributeData(String propertyName, String ldapAttributeName, Getter propertyValueGetter, - Object entry, boolean multiValued, boolean jsonObject) { - Object propertyValue = propertyValueGetter.get(entry); - if (propertyValue == null) { - return null; - } - - Object[] attributeValues = getAttributeValues(propertyName, jsonObject, propertyValue); - - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Property: %s, LdapProperty: %s, PropertyValue: %s", propertyName, - ldapAttributeName, Arrays.toString(attributeValues))); - } - - if (attributeValues.length == 0) { - attributeValues = new String[] {}; - } else if ((attributeValues.length == 1) && (attributeValues[0] == null)) { - return null; - } - - return new AttributeData(ldapAttributeName, attributeValues, multiValued); - } - - private Object[] getAttributeValues(String propertyName, boolean jsonObject, Object propertyValue) { - Object[] attributeValues = new Object[1]; - - boolean nativeType = getNativeAttributeValue(propertyValue, attributeValues); - if (nativeType) { - // We do conversion in getNativeAttributeValue method already - } else if (propertyValue instanceof AttributeEnum) { - attributeValues[0] = ((AttributeEnum) propertyValue).getValue(); - } else if (propertyValue instanceof AttributeEnum[]) { - AttributeEnum[] propertyValues = (AttributeEnum[]) propertyValue; - attributeValues = new String[propertyValues.length]; - for (int i = 0; i < propertyValues.length; i++) { - attributeValues[i] = (propertyValues[i] == null) ? null : propertyValues[i].getValue(); - } - } else if (propertyValue instanceof String[]) { - attributeValues = (String[]) propertyValue; - } else if (propertyValue instanceof Object[]) { - attributeValues = (Object[]) propertyValue; - } else if (propertyValue instanceof List) { - attributeValues = new Object[((List) propertyValue).size()]; - int index = 0; - Object nativeAttributeValue[] = new Object[1]; - for (Object tmpPropertyValue : (List) propertyValue) { - if (jsonObject) { - attributeValues[index++] = convertValueToJson(tmpPropertyValue); - } else { - if (getNativeAttributeValue(tmpPropertyValue, nativeAttributeValue)) { - attributeValues[index++] = nativeAttributeValue[0]; - } else { - attributeValues[index++] = StringHelper.toString(tmpPropertyValue); - } - } - } - } else if (jsonObject) { - attributeValues[0] = convertValueToJson(propertyValue); - } else { - throw new MappingException("Entry property '" + propertyName - + "' should has getter with String, String[], Boolean, Integer, Long, Date, List, AttributeEnum or AttributeEnum[]" - + " return type or has annotation JsonObject"); - } - return attributeValues; - } - - /* - * This method doesn't produces new object to avoid extra garbage creation - */ - private boolean getNativeAttributeValue(Object propertyValue, Object[] resultValue) { - // Clean result - resultValue[0] = null; - - if (propertyValue instanceof String) { - resultValue[0] = StringHelper.toString(propertyValue); - } else if (propertyValue instanceof Boolean) { - resultValue[0] = propertyValue; - } else if (propertyValue instanceof Integer) { - resultValue[0] = propertyValue; - } else if (propertyValue instanceof Long) { - resultValue[0] = propertyValue; - } else if (propertyValue instanceof Date) { - resultValue[0] = encodeTime((Date) propertyValue); - } else { - return false; - } - - return true; - } - - protected boolean isAttributeMultivalued(Object[] values) { - if (values.length > 1) { - return true; - - } - - return false; - } - - protected Object convertValueToJson(Object propertyValue) { - try { - String value = JSON_OBJECT_MAPPER.writeValueAsString(propertyValue); - - return value; - } catch (Exception ex) { - LOG.error("Failed to convert '{}' to json value:", propertyValue, ex); - throw new MappingException(String.format("Failed to convert '%s' to json value", propertyValue)); - } - } - - protected List getAttributesListForPersist(Object entry, - List propertiesAnnotations) { - // Prepare list of properties to persist - List attributes = new ArrayList(); - for (PropertyAnnotation propertiesAnnotation : propertiesAnnotations) { - String propertyName = propertiesAnnotation.getPropertyName(); - Annotation ldapAttribute; - - // Process properties with AttributeName annotation - ldapAttribute = ReflectHelper.getAnnotationByType(propertiesAnnotation.getAnnotations(), - AttributeName.class); - if (ldapAttribute != null) { - AttributeData attribute = getAttributeDataFromAttribute(entry, ldapAttribute, propertiesAnnotation, - propertyName); - if (attribute != null) { - attributes.add(attribute); - } - - continue; - } - - // Process properties with @AttributesList annotation - ldapAttribute = ReflectHelper.getAnnotationByType(propertiesAnnotation.getAnnotations(), - AttributesList.class); - if (ldapAttribute != null) { - List listAttributes = getAttributesFromAttributesList(entry, ldapAttribute, - propertyName); - if (listAttributes != null) { - attributes.addAll(listAttributes); - } - - continue; - } - } - - return attributes; - } - - private AttributeData getAttributeDataFromAttribute(Object entry, Annotation ldapAttribute, - PropertyAnnotation propertiesAnnotation, String propertyName) { - Class entryClass = entry.getClass(); - - String ldapAttributeName = ((AttributeName) ldapAttribute).name(); - if (StringHelper.isEmpty(ldapAttributeName)) { - ldapAttributeName = propertyName; - } - - Getter getter = getGetter(entryClass, propertyName); - if (getter == null) { - throw new MappingException("Entry should has getter for property " + propertyName); - } - - Class parameterType = getSetterPropertyType(entryClass, propertyName); - boolean multiValued = isMultiValued(parameterType); - - Annotation ldapJsonObject = ReflectHelper.getAnnotationByType(propertiesAnnotation.getAnnotations(), - JsonObject.class); - boolean jsonObject = ldapJsonObject != null; - AttributeData attribute = getAttributeData(propertyName, ldapAttributeName, getter, entry, multiValued, jsonObject); - - return attribute; - } - - private List getAttributesFromAttributesList(Object entry, Annotation ldapAttribute, - String propertyName) { - Class entryClass = entry.getClass(); - List listAttributes = new ArrayList(); - - Getter getter = getGetter(entryClass, propertyName); - if (getter == null) { - throw new MappingException("Entry should has getter for property " + propertyName); - } - - Object propertyValue = getter.get(entry); - if (propertyValue == null) { - return null; - } - - if (!(propertyValue instanceof List)) { - throw new MappingException("Entry property should has List base type"); - } - - Class elementType = ReflectHelper.getListType(getter); - - String entryPropertyName = ((AttributesList) ldapAttribute).name(); - Getter entryPropertyNameGetter = getGetter(elementType, entryPropertyName); - if (entryPropertyNameGetter == null) { - throw new MappingException( - "Entry should has getter for property " + propertyName + "." + entryPropertyName); - } - - String entryPropertyValue = ((AttributesList) ldapAttribute).value(); - Getter entryPropertyValueGetter = getGetter(elementType, entryPropertyValue); - if (entryPropertyValueGetter == null) { - throw new MappingException( - "Entry should has getter for property " + propertyName + "." + entryPropertyValue); - } - - String entryPropertyMultivalued = ((AttributesList) ldapAttribute).multiValued(); - Getter entryPropertyMultivaluedGetter = null; - if (StringHelper.isNotEmpty(entryPropertyMultivalued)) { - entryPropertyMultivaluedGetter = getGetter(elementType, entryPropertyMultivalued); - } - if (entryPropertyMultivaluedGetter != null) { - Class propertyType = entryPropertyMultivaluedGetter.getReturnType(); - if (!propertyType.equals(Boolean.TYPE)) { - throw new MappingException( - "Entry should has getter for property " + propertyName + "." + entryPropertyMultivalued + " with boolean type"); - } - } - - for (Object entryAttribute : (List) propertyValue) { - AttributeData attribute = getAttributeData(propertyName, entryPropertyNameGetter, entryPropertyValueGetter, - entryAttribute, false); - if (attribute != null) { - if (entryPropertyMultivaluedGetter != null) { - boolean multiValued = (boolean) entryPropertyMultivaluedGetter.get(entryAttribute); - attribute.setMultiValued(multiValued); - } else { - // Detect if attribute has more than one value - boolean multiValued = attribute.getValues().length > 1; - attribute.setMultiValued(multiValued); - } - - listAttributes.add(attribute); - } - } - - return listAttributes; - } - - protected List getEntryPropertyAnnotations(Class entryClass) { - final List annotations = getEntryClassAnnotations(entryClass, "property_", LDAP_ENTRY_PROPERTY_ANNOTATIONS); -// KeyShortcuter.initIfNeeded(entryClass, annotations); - return annotations; - } - - protected List getEntryDnAnnotations(Class entryClass) { - return getEntryClassAnnotations(entryClass, "dn_", LDAP_DN_PROPERTY_ANNOTATION); - } - - protected List getEntryCustomObjectClassAnnotations(Class entryClass) { - return getEntryClassAnnotations(entryClass, "custom_", LDAP_CUSTOM_OBJECT_CLASS_PROPERTY_ANNOTATION); - } - - protected List getEntryClassAnnotations(Class entryClass, String keyCategory, - Class[] annotationTypes) { - String key = keyCategory + entryClass.getName(); - - List annotations = classAnnotations.get(key); - if (annotations == null) { - synchronized (CLASS_ANNOTATIONS_LOCK) { - annotations = classAnnotations.get(key); - if (annotations == null) { - Map> annotationsMap = ReflectHelper.getPropertiesAnnotations(entryClass, - annotationTypes); - annotations = convertToPropertyAnnotationList(annotationsMap); - classAnnotations.put(key, annotations); - } - } - } - - return annotations; - } - - private List convertToPropertyAnnotationList(Map> annotations) { - List result = new ArrayList(annotations.size()); - for (Entry> entry : annotations.entrySet()) { - result.add(new PropertyAnnotation(entry.getKey(), entry.getValue())); - } - - Collections.sort(result); - - return result; - } - - protected Getter getGetter(Class entryClass, String propertyName) { - String key = entryClass.getName() + "." + propertyName; - - Getter getter = classGetters.get(key); - if (getter == null) { - synchronized (CLASS_GETTERS_LOCK) { - getter = classGetters.get(key); - if (getter == null) { - getter = ReflectHelper.getGetter(entryClass, propertyName); - classGetters.put(key, getter); - } - } - } - - return getter; - } - - protected Setter getSetter(Class entryClass, String propertyName) { - String key = entryClass.getName() + "." + propertyName; - - Setter setter = classSetters.get(key); - if (setter == null) { - synchronized (CLASS_SETTERS_LOCK) { - setter = classSetters.get(key); - if (setter == null) { - setter = ReflectHelper.getSetter(entryClass, propertyName); - classSetters.put(key, setter); - } - } - } - - return setter; - } - - private AttributeData getAttributeData(String propertyName, Getter propertyNameGetter, Getter propertyValueGetter, - Object entry, boolean jsonObject) { - Object ldapAttributeName = propertyNameGetter.get(entry); - if (ldapAttributeName == null) { - return null; - } - - return getAttributeData(propertyName, ldapAttributeName.toString(), propertyValueGetter, entry, false, jsonObject); - } - - private void setPropertyValue(String propertyName, Setter propertyValueSetter, Object entry, - AttributeData attribute, boolean jsonObject) { - if (attribute == null) { - return; - } - - LOG.debug(String.format("LdapProperty: %s, AttributeName: %s, AttributeValue: %s", propertyName, - attribute.getName(), Arrays.toString(attribute.getValues()))); - - Class parameterType = ReflectHelper.getSetterType(propertyValueSetter); - if (parameterType.equals(String.class)) { - Object value = attribute.getValue(); - if (value instanceof Date) { - value = encodeTime((Date) value); - } - propertyValueSetter.set(entry, String.valueOf(value)); - } else if (parameterType.equals(Boolean.class) || parameterType.equals(Boolean.TYPE)) { - propertyValueSetter.set(entry, toBooleanValue(attribute)); - } else if (parameterType.equals(Integer.class) || parameterType.equals(Integer.TYPE)) { - propertyValueSetter.set(entry, toIntegerValue(attribute)); - } else if (parameterType.equals(Long.class) || parameterType.equals(Long.TYPE)) { - propertyValueSetter.set(entry, toLongValue(attribute)); - } else if (parameterType.equals(Date.class)) { - propertyValueSetter.set(entry, attribute.getValue() instanceof Date ? (Date) attribute.getValue() : decodeTime(String.valueOf(attribute.getValue()))); - } else if (parameterType.equals(String[].class)) { - propertyValueSetter.set(entry, attribute.getStringValues()); - } else if (ReflectHelper.assignableFrom(parameterType, List.class)) { - if (jsonObject) { - Object[] values = attribute.getValues(); - List jsonValues = new ArrayList(values.length); - - for (Object value : values) { - Object jsonValue = convertJsonToValue(ReflectHelper.getListType(propertyValueSetter), value); - jsonValues.add(jsonValue); - } - propertyValueSetter.set(entry, jsonValues); - } else { - List resultValues = attributeToTypedList(ReflectHelper.getListType(propertyValueSetter), attribute); - propertyValueSetter.set(entry, resultValues); - } - } else if (ReflectHelper.assignableFrom(parameterType, AttributeEnum.class)) { - try { - propertyValueSetter.set(entry, parameterType.getMethod("resolveByValue", String.class) - .invoke(parameterType.getEnumConstants()[0], attribute.getValue())); - } catch (Exception ex) { - throw new MappingException("Failed to resolve Enum '" + parameterType + "' by value '" + attribute.getValue() + "'", ex); - } - } else if (ReflectHelper.assignableFrom(parameterType, AttributeEnum[].class)) { - Class itemType = parameterType.getComponentType(); - Method enumResolveByValue; - try { - enumResolveByValue = itemType.getMethod("resolveByValue", String.class); - } catch (Exception ex) { - throw new MappingException("Failed to resolve Enum '" + parameterType + "' by value '" + Arrays.toString(attribute.getValues()) + "'", - ex); - } - - Object[] attributeValues = attribute.getValues(); - AttributeEnum[] ldapEnums = (AttributeEnum[]) ReflectHelper.createArray(itemType, attributeValues.length); - for (int i = 0; i < attributeValues.length; i++) { - try { - ldapEnums[i] = (AttributeEnum) enumResolveByValue.invoke(itemType.getEnumConstants()[0], - attributeValues[i]); - } catch (Exception ex) { - throw new MappingException( - "Failed to resolve Enum '" + parameterType + "' by value '" + Arrays.toString(attribute.getValues()) + "'", ex); - } - } - propertyValueSetter.set(entry, ldapEnums); - } else if (jsonObject) { - Object stringValue = attribute.getValue(); - Object jsonValue = convertJsonToValue(parameterType, stringValue); - propertyValueSetter.set(entry, jsonValue); - } else { - throw new MappingException("Entry property '" + propertyName - + "' should has setter with String, Boolean, Integer, Long, Date, String[], List, AttributeEnum or AttributeEnum[]" - + " parameter type or has annotation JsonObject"); - } - } - - private List attributeToTypedList(Class listType, AttributeData attributeData) { - if (listType.equals(String.class)) { - ArrayList result = new ArrayList(); - for (Object value : attributeData.getValues()) { - String resultValue; - if (value instanceof Date) { - resultValue = encodeTime((Date) value); - } else { - resultValue = String.valueOf(value); - } - - result.add(resultValue); - } - - return result; - } - - return Arrays.asList(attributeData.getValues()); - } - - private Boolean toBooleanValue(AttributeData attribute) { - Boolean propertyValue = null; - Object propertyValueObject = attribute.getValue(); - if (propertyValueObject != null) { - if (propertyValueObject instanceof Boolean) { - propertyValue = (Boolean) propertyValueObject; - } else { - propertyValue = Boolean.valueOf(String.valueOf(propertyValueObject)); - } - } - return propertyValue; - } - - private Integer toIntegerValue(AttributeData attribute) { - Integer propertyValue = null; - Object propertyValueObject = attribute.getValue(); - if (propertyValueObject != null) { - if (propertyValueObject instanceof Long) { - propertyValue = (Integer) propertyValueObject; - } else { - propertyValue = Integer.valueOf(String.valueOf(propertyValueObject)); - } - } - return propertyValue; - } - - private Long toLongValue(AttributeData attribute) { - Long propertyValue = null; - Object propertyValueObject = attribute.getValue(); - if (propertyValueObject != null) { - if (propertyValueObject instanceof Long) { - propertyValue = (Long) propertyValueObject; - } else { - propertyValue = Long.valueOf(String.valueOf(propertyValueObject)); - } - } - return propertyValue; - } - - protected Object convertJsonToValue(Class parameterType, Object propertyValue) { - try { - Object jsonValue = JSON_OBJECT_MAPPER.readValue(String.valueOf(propertyValue), parameterType); - return jsonValue; - } catch (Exception ex) { - LOG.error("Failed to convert json value '{}' to object `{}`", propertyValue, parameterType, ex); - throw new MappingException(String.format("Failed to convert json value '%s' to object of type %s", - propertyValue, parameterType)); - } - } - - private Object getListItem(String propertyName, Setter propertyNameSetter, Setter propertyValueSetter, - Setter entryPropertyMultivaluedSetter, Class classType, AttributeData attribute) { - if (attribute == null) { - return null; - } - - Object result; - try { - result = ReflectHelper.createObjectByDefaultConstructor(classType); - } catch (Exception ex) { - throw new MappingException(String.format("Entry %s should has default constructor", classType)); - } - propertyNameSetter.set(result, attribute.getName()); - setPropertyValue(propertyName, propertyValueSetter, result, attribute, false); - - if ((entryPropertyMultivaluedSetter != null) && (attribute.getMultiValued() != null)) { - entryPropertyMultivaluedSetter.set(result, attribute.getMultiValued()); - } - - return result; - } - - protected Object getDNValue(Object entry, Class entryClass) { - // Check if entry has DN property - String dnProperty = getDNPropertyName(entryClass); - - // Get DN value - Getter dnGetter = getGetter(entryClass, dnProperty); - if (dnGetter == null) { - throw new MappingException("Entry should has getter for property " + dnProperty); - } - - Object dnValue = dnGetter.get(entry); - if (StringHelper.isEmptyString(dnValue)) { - throw new MappingException("Entry should has not null base DN property value"); - } - - return dnValue; - } - - private String getEntryKey(T entry, boolean caseSensetive, Getter[] propertyGetters) { - StringBuilder sb = new StringBuilder("key"); - for (Getter getter : propertyGetters) { - sb.append("__").append(getter.get(entry)); - } - - if (caseSensetive) { - return sb.toString(); - } else { - return sb.toString().toLowerCase(); - } - } - - private Map getAttributesDataMap(List attributesData) { - Map result = new HashMap(); - - for (AttributeData attributeData : attributesData) { - result.put(attributeData.getName(), attributeData); - } - - return result; - } - - private String getEntryKey(Object dnValue, boolean caseSensetive, List propertiesAnnotations, - List attributesData) { - StringBuilder sb = new StringBuilder("_HASH__").append((String.valueOf(dnValue)).toLowerCase()).append("__"); - - List processedProperties = new ArrayList(); - Map attributesDataMap = getAttributesDataMap(attributesData); - for (PropertyAnnotation propertiesAnnotation : propertiesAnnotations) { - Annotation ldapAttribute = ReflectHelper.getAnnotationByType(propertiesAnnotation.getAnnotations(), - AttributeName.class); - if (ldapAttribute == null) { - continue; - } - - String ldapAttributeName = ((AttributeName) ldapAttribute).name(); - if (StringHelper.isEmpty(ldapAttributeName)) { - ldapAttributeName = propertiesAnnotation.getPropertyName(); - } - - processedProperties.add(ldapAttributeName); - - String[] values = null; - - AttributeData attributeData = attributesDataMap.get(ldapAttributeName); - if ((attributeData != null) && (attributeData.getValues() != null)) { - values = attributeData.getStringValues(); - Arrays.sort(values); - } - - addPropertyWithValuesToKey(sb, ldapAttributeName, values); - } - - for (AttributeData attributeData : attributesData) { - if (processedProperties.contains(attributeData.getName())) { - continue; - } - - addPropertyWithValuesToKey(sb, attributeData.getName(), attributeData.getStringValues()); - } - - if (caseSensetive) { - return sb.toString(); - } else { - return sb.toString().toLowerCase(); - } - } - - private void addPropertyWithValuesToKey(StringBuilder sb, String propertyName, String[] values) { - sb.append(':').append(propertyName).append('='); - if (values == null) { - sb.append("null"); - } else { - if (values.length == 1) { - sb.append(values[0]); - } else { - String[] tmpValues = values.clone(); - Arrays.sort(tmpValues); - - for (int i = 0; i < tmpValues.length; i++) { - sb.append(tmpValues[i]); - if (i < tmpValues.length - 1) { - sb.append(';'); - } - } - } - } - } - - @Override - public int getHashCode(Object entry) { - if (entry == null) { - throw new MappingException("Entry to persist is null"); - } - - // Check entry class - Class entryClass = entry.getClass(); - checkEntryClass(entryClass, false); - List propertiesAnnotations = getEntryPropertyAnnotations(entryClass); - - Object dnValue = getDNValue(entry, entryClass); - - List attributes = getAttributesListForPersist(entry, propertiesAnnotations); - String key = getEntryKey(dnValue, false, propertiesAnnotations, attributes); - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Entry key HashCode is: %s", key.hashCode())); - } - - return key.hashCode(); - } - - protected byte[][] toBinaryValues(String[] attributeValues) { - byte[][] binaryValues = new byte[attributeValues.length][]; - - for (int i = 0; i < attributeValues.length; i++) { - binaryValues[i] = Base64.decodeBase64(attributeValues[i]); - } - return binaryValues; - } - - protected Filter createFilterByEntry(Object entry, Class entryClass, List attributes) { - Filter[] attributesFilters = createAttributesFilter(attributes); - Filter attributesFilter = null; - if (attributesFilters != null) { - attributesFilter = Filter.createANDFilter(attributesFilters); - } - - String[] objectClasses = getObjectClasses(entry, entryClass); - return addObjectClassFilter(attributesFilter, objectClasses); - } - - protected Filter[] createAttributesFilter(List attributes) { - if ((attributes == null) || (attributes.size() == 0)) { - return null; - } - - List results = new ArrayList(attributes.size()); - - for (AttributeData attribute : attributes) { - String attributeName = attribute.getName(); - for (Object value : attribute.getValues()) { - Filter filter = Filter.createEqualityFilter(attributeName, value); - if ((attribute.getMultiValued() != null) && attribute.getMultiValued()) { - filter.multiValued(); - } - - results.add(filter); - } - } - - return results.toArray(new Filter[results.size()]); - } - - protected Filter addObjectClassFilter(Filter filter, String[] objectClasses) { - if (objectClasses.length == 0) { - return filter; - } - - Filter[] objectClassFilter = new Filter[objectClasses.length]; - for (int i = 0; i < objectClasses.length; i++) { - objectClassFilter[i] = Filter.createEqualityFilter(OBJECT_CLASS, objectClasses[i]).multiValued(); - } - Filter searchFilter = Filter.createANDFilter(objectClassFilter); - if (filter != null) { - searchFilter = Filter.createANDFilter(Filter.createANDFilter(objectClassFilter), filter); - } - return searchFilter; - } - - protected boolean isMultiValued(Class parameterType) { - if (parameterType == null) { - return false; - } - - boolean isMultiValued = parameterType.equals(String[].class) || ReflectHelper.assignableFrom(parameterType, List.class) || ReflectHelper.assignableFrom(parameterType, AttributeEnum[].class); - - return isMultiValued; - } - - protected abstract Date decodeTime(String date); - - protected abstract String encodeTime(Date date); - - protected static final class PropertyComparator implements Comparator, Serializable { - - private static final long serialVersionUID = 574848841116711467L; - private Getter[][] propertyGetters; - private boolean caseSensetive; - - private PropertyComparator(Getter[][] propertyGetters, boolean caseSensetive) { - this.propertyGetters = propertyGetters; - this.caseSensetive = caseSensetive; - } - - @Override - public int compare(T entry1, T entry2) { - if ((entry1 == null) && (entry2 == null)) { - return 0; - } - if ((entry1 == null) && (entry2 != null)) { - return -1; - } else if ((entry1 != null) && (entry2 == null)) { - return 1; - } - - int result = 0; - for (Getter[] curPropertyGetters : propertyGetters) { - result = compare(entry1, entry2, curPropertyGetters); - if (result != 0) { - break; - } - } - - return result; - } - - public int compare(T entry1, T entry2, Getter[] propertyGetters) { - Object value1 = ReflectHelper.getPropertyValue(entry1, propertyGetters); - Object value2 = ReflectHelper.getPropertyValue(entry2, propertyGetters); - - if ((value1 == null) && (value2 == null)) { - return 0; - } - if ((value1 == null) && (value2 != null)) { - return -1; - } else if ((value1 != null) && (value2 == null)) { - return 1; - } - - if (value1 instanceof Date) { - return ((Date) value1).compareTo((Date) value2); - } else if (value1 instanceof Integer) { - return ((Integer) value1).compareTo((Integer) value2); - } else if (value1 instanceof String && value2 instanceof String) { - if (caseSensetive) { - return ((String) value1).compareTo((String) value2); - } else { - return ((String) value1).toLowerCase().compareTo(((String) value2).toLowerCase()); - } - } - return 0; - } - } - - protected static final class LineLenghtComparator implements Comparator, Serializable { - - private static final long serialVersionUID = 575848841116711467L; - private boolean ascending; - - public LineLenghtComparator(boolean ascending) { - this.ascending = ascending; - } - - @Override - public int compare(T entry1, T entry2) { - if ((entry1 == null) && (entry2 == null)) { - return 0; - } - if ((entry1 == null) && (entry2 != null)) { - return -1; - } else if ((entry1 != null) && (entry2 == null)) { - return 1; - } - - int result = entry1.toString().length() - entry2.toString().length(); - if (ascending) { - return result; - } else { - return -result; - } - } - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/key/impl/GenericKeyConverter.java b/persistence-core/src/main/java/org/gluu/persist/key/impl/GenericKeyConverter.java deleted file mode 100644 index 4e3b2c08d..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/key/impl/GenericKeyConverter.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - /* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2018, Gluu - */ - -package org.gluu.persist.key.impl; - -import org.gluu.persist.exception.KeyConversionException; -import org.gluu.persist.key.impl.model.ParsedKey; -import org.gluu.util.StringHelper; - -/** - * DN to Generic key convert - * - * @author Yuriy Movchan Date: 05/30/2018 - */ -public class GenericKeyConverter { - - public ParsedKey convertToKey(String dn) { - if (StringHelper.isEmpty(dn)) { - throw new KeyConversionException("Failed to convert empty DN to Key"); - } - - StringBuilder result = new StringBuilder(); - String[] tokens = dn.split(","); - - String orgInum = null; - String attributeName = null; - for (String token : tokens) { - int pos = token.indexOf("="); - if (pos == -1) { - throw new KeyConversionException("Failed to convert empty DN to Key"); - } - - String name = token.substring(0, pos); - if (attributeName == null) { - attributeName = name; - } - String value = token.substring(pos + 1, token.length()); - if (StringHelper.equalsIgnoreCase(name, "o")) { - if (!StringHelper.equalsIgnoreCase(value, "gluu")) { - orgInum = value; - } - continue; - } - - result.insert(0, "_" + value); - } - - String key = result.toString(); - if (key.length() == 0) { - key = "_"; - } else { - key = key.substring(1); - } - - return new ParsedKey(key, attributeName, orgInum); - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/key/impl/KeyShortcuter.java b/persistence-core/src/main/java/org/gluu/persist/key/impl/KeyShortcuter.java deleted file mode 100644 index 7d6adea86..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/key/impl/KeyShortcuter.java +++ /dev/null @@ -1,126 +0,0 @@ -package org.gluu.persist.key.impl; - -import com.google.common.collect.BiMap; -import com.google.common.collect.HashBiMap; -import com.google.common.collect.Lists; -import org.apache.commons.lang.StringUtils; -import org.gluu.persist.annotation.AttributeName; -import org.gluu.persist.annotation.AttributesList; -import org.gluu.persist.reflect.property.PropertyAnnotation; -import org.gluu.persist.reflect.util.ReflectHelper; -import org.gluu.util.Util; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.io.InputStream; -import java.lang.annotation.Annotation; -import java.util.List; -import java.util.Map; - -/** - * Utility class which provides shorter version of the key - * - * @author Yuriy Zabrovarnyy - */ -public class KeyShortcuter { - - private static final Logger LOG = LoggerFactory.getLogger(KeyShortcuter.class); - - public static final String CONF_FILE_NAME = "key-shortcuter-rules.json"; - - private static final List PROCESSED_ENTRIES = Lists.newArrayList(); - - private static final BiMap MAP = HashBiMap.create(); - private static final BiMap INVERSE_MAP = MAP.inverse(); - - private KeyShortcuter() { - } - - private static KeyShortcuterConf conf = load(); - - private static KeyShortcuterConf load() { - try (InputStream is = KeyShortcuter.class.getResourceAsStream("/" + CONF_FILE_NAME)) { - return Util.createJsonMapper().readValue(is, KeyShortcuterConf.class); - } catch (IOException e) { - LOG.error("Failed to load key shortcuter configuration from file: " + CONF_FILE_NAME, e); - return null; - } - } - - public static String fromShortcut(String shortcut) { - return INVERSE_MAP.getOrDefault(shortcut, shortcut); - } - - public static String shortcut(String key) { - if (conf == null) { - LOG.error("Failed to load key shortcuter configuration from file: " + CONF_FILE_NAME); - return key; - } - if (StringUtils.isBlank(key)) { - return key; - } - - final String cachedShortcut = MAP.get(key); - if (cachedShortcut != null) { - return cachedShortcut; - } - - String copy = key; - - final String exclusion = conf.getExclusions().get(key); - if (StringUtils.isNotBlank(exclusion)) { - MAP.put(copy, exclusion); - return exclusion; - } - - for (String prefix : conf.getPrefixes()) { - if (key.startsWith(prefix)) { - key = StringUtils.removeStart(key, prefix); - } - } - - for (Map.Entry replace : conf.getReplaces().entrySet()) { - key = StringUtils.replace(key, replace.getKey(), replace.getValue()); - } - - key = lowercaseFirstChar(key); - try { - MAP.put(copy, key); - } catch (IllegalArgumentException e) { - LOG.error("Found duplicate for key: " + key + ", duplicate from: " + MAP.inverse().get(key)); - return copy; // skip shortcuting and return original key - } - return key; - } - - public static String lowercaseFirstChar(String key) { - return Character.toLowerCase(key.charAt(0)) + key.substring(1); - } - - public static void initIfNeeded(Class entryClass, List propertiesAnnotations) { - if (entryClass == null || propertiesAnnotations == null || PROCESSED_ENTRIES.contains(entryClass)) { - return; - } - - for (PropertyAnnotation propertiesAnnotation : propertiesAnnotations) { - // Process properties with AttributeName annotation - Annotation annotation = ReflectHelper.getAnnotationByType(propertiesAnnotation.getAnnotations(), AttributeName.class); - if (annotation != null) { - shortcut(((AttributeName) annotation).name()); - continue; - } - - // Process properties with @AttributesList annotation - annotation = ReflectHelper.getAnnotationByType(propertiesAnnotation.getAnnotations(), AttributesList.class); - if (annotation != null) { - for (AttributeName attributeConfiguration : ((AttributesList) annotation).attributesConfiguration()) { - shortcut(attributeConfiguration.name()); - } - } - } - - - PROCESSED_ENTRIES.add(entryClass); - } -} diff --git a/persistence-core/src/main/java/org/gluu/persist/key/impl/KeyShortcuterConf.java b/persistence-core/src/main/java/org/gluu/persist/key/impl/KeyShortcuterConf.java deleted file mode 100644 index 656789397..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/key/impl/KeyShortcuterConf.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.gluu.persist.key.impl; - -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.List; -import java.util.Map; - -/** - * @author Yuriy Zabrovarnyy - */ -public class KeyShortcuterConf { - - @JsonProperty - private List prefixes; - @JsonProperty - private Map replaces; - @JsonProperty - private Map exclusions; - - public List getPrefixes() { - return prefixes; - } - - public void setPrefixes(List prefixes) { - this.prefixes = prefixes; - } - - public Map getReplaces() { - return replaces; - } - - public void setReplaces(Map replaces) { - this.replaces = replaces; - } - - public Map getExclusions() { - return exclusions; - } - - public void setExclusions(Map exclusions) { - this.exclusions = exclusions; - } - - @Override - public String toString() { - return "KeyShortcuterConf{" + - "prefixes=" + prefixes + - ", replaces=" + replaces + - ", exclusions=" + exclusions + - '}'; - } -} diff --git a/persistence-core/src/main/java/org/gluu/persist/key/impl/model/ParsedKey.java b/persistence-core/src/main/java/org/gluu/persist/key/impl/model/ParsedKey.java deleted file mode 100644 index a971f1c34..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/key/impl/model/ParsedKey.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2018, Gluu - */ -package org.gluu.persist.key.impl.model; - -/** - * Couchbase key with inum - * - * @author Yuriy Movchan Date: 05/31/2018 - */ -public class ParsedKey { - - private final String key; - private final String name; - private final String inum; - - public ParsedKey(final String key, final String name, String inum) { - this.key = key; - this.name = name; - this.inum = inum; - } - - public final String getKey() { - return key; - } - - public String getName() { - return name; - } - - public final String getInum() { - return inum; - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/model/AttributeData.java b/persistence-core/src/main/java/org/gluu/persist/model/AttributeData.java deleted file mode 100644 index 2d9e0036f..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/model/AttributeData.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.model; - -import java.util.Arrays; - -import org.gluu.util.ArrayHelper; -import org.gluu.util.StringHelper; - -/** - * LDAP Attribute - * - * @author Yuriy Movchan Date: 10.10.2010 - */ -public class AttributeData { - private final String name; - private final Object[] values; - private Boolean multiValued; - - public AttributeData(String name, Object[] values) { - this(name, values, null); - } - - public AttributeData(String name, Object[] values, Boolean multiValued) { - this.name = name; - this.values = values; - this.multiValued = multiValued; - } - - public AttributeData(String name, Object value) { - this.name = name; - this.values = new Object[1]; - this.values[0] = value; - this.multiValued = null; - } - - public final String getName() { - return name; - } - - public final Object[] getValues() { - return values; - } - - public final String[] getStringValues() { - return StringHelper.toStringArray(this.values); - } - - public Object getValue() { - if ((this.values == null) || (this.values.length == 0)) { - return null; - } - - return this.values[0]; - } - - public void setMultiValued(Boolean multiValued) { - this.multiValued = multiValued; - } - - public Boolean getMultiValued() { - return multiValued; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((multiValued == null) ? 0 : multiValued.hashCode()); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + Arrays.deepHashCode(values); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - AttributeData other = (AttributeData) obj; - if ((multiValued != null) && (other.multiValued != null)) { - if (!multiValued.equals(other.multiValued)) - return false; - } - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - - if ((values == null) && (other.values == null)) { - return true; - } - - if ((values == null) || (other.values == null) || values.length != other.values.length) { - return false; - } - - for (int i = 0; i < values.length; i++) { - if (!StringHelper.equals(String.valueOf(values[i]), String.valueOf(other.values[i]))) { - return false; - } - } - - return true; - } - - @Override - public String toString() { - return "AttributeData [name=" + name + ", values=" + Arrays.toString(values) + ", multiValued=" + multiValued + "]"; - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/model/AttributeDataModification.java b/persistence-core/src/main/java/org/gluu/persist/model/AttributeDataModification.java deleted file mode 100644 index 8cd3df662..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/model/AttributeDataModification.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.model; - -/** - * LDAP Attribute - * - * @author Yuriy Movchan Date: 10.10.2010 - */ -public class AttributeDataModification { - - public enum AttributeModificationType { - ADD, REMOVE, REPLACE; - } - - private final AttributeModificationType modificationType; - private final AttributeData attribute; - private final AttributeData oldAttribute; - - public AttributeDataModification(AttributeModificationType modificationType, AttributeData attribute) { - this(modificationType, attribute, null); - } - - public AttributeDataModification(AttributeModificationType modificationType, AttributeData attribute, AttributeData oldAttribute) { - this.modificationType = modificationType; - this.attribute = attribute; - this.oldAttribute = oldAttribute; - } - - public final AttributeModificationType getModificationType() { - return modificationType; - } - - public final AttributeData getOldAttribute() { - return oldAttribute; - } - - public final AttributeData getAttribute() { - return attribute; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((modificationType == null) ? 0 : modificationType.hashCode()); - result = prime * result + ((attribute == null) ? 0 : attribute.hashCode()); - result = prime * result + ((oldAttribute == null) ? 0 : oldAttribute.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - AttributeDataModification other = (AttributeDataModification) obj; - if (modificationType == null) { - if (other.modificationType != null) { - return false; - } - } else if (!modificationType.equals(other.modificationType)) { - return false; - } - if (attribute == null) { - if (other.attribute != null) { - return false; - } - } else if (!attribute.equals(other.attribute)) { - return false; - } - if (oldAttribute == null) { - if (other.oldAttribute != null) { - return false; - } - } else if (!oldAttribute.equals(other.oldAttribute)) { - return false; - } - return true; - } - - @Override - public String toString() { - return String.format("AttributeModification [modificationType=%s, attribute=%s, oldAttribute=%s]", modificationType, attribute, - oldAttribute); - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/model/BatchOperation.java b/persistence-core/src/main/java/org/gluu/persist/model/BatchOperation.java deleted file mode 100644 index 957bff497..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/model/BatchOperation.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2018, Gluu - */ - -package org.gluu.persist.model; - -import java.util.List; - -/** - * Batch operation - * - * @author Yuriy Movchan Date: 01/29/2018 - */ -public interface BatchOperation { - - boolean collectSearchResult(int size); - - void performAction(List entries); - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/model/DefaultBatchOperation.java b/persistence-core/src/main/java/org/gluu/persist/model/DefaultBatchOperation.java deleted file mode 100644 index 02c4ede4c..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/model/DefaultBatchOperation.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2018, Gluu - */ - -package org.gluu.persist.model; - -/** - * @author Yuriy Movchan Date: 02/07/2018 - */ -public abstract class DefaultBatchOperation implements BatchOperation { - - public boolean collectSearchResult(int size) { - return true; - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/model/PagedResult.java b/persistence-core/src/main/java/org/gluu/persist/model/PagedResult.java deleted file mode 100644 index d2b458ff6..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/model/PagedResult.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ -package org.gluu.persist.model; - -import java.io.Serializable; -import java.util.List; - -/** - * @author Val Pecaoco - * @author Yuriy Movchan Date: 01/25/2018 - */ -public class PagedResult implements Serializable { - - private static final long serialVersionUID = -4211997747213144092L; - - private int start; - - private int totalEntriesCount; - - private int entriesCount; - - private List entries; - - public int getTotalEntriesCount() { - return totalEntriesCount; - } - - public void setTotalEntriesCount(int totalEntriesCount) { - this.totalEntriesCount = totalEntriesCount; - } - - public int getEntriesCount() { - return entriesCount; - } - - public void setEntriesCount(int entriesCount) { - this.entriesCount = entriesCount; - } - - public int getStart() { - return start; - } - - public void setStart(int start) { - this.start = start; - } - - public final List getEntries() { - return entries; - } - - public final void setEntries(List entries) { - this.entries = entries; - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/model/PersistenceConfiguration.java b/persistence-core/src/main/java/org/gluu/persist/model/PersistenceConfiguration.java deleted file mode 100644 index 22d8f1192..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/model/PersistenceConfiguration.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.gluu.persist.model; - -import org.gluu.persist.PersistenceEntryManagerFactory; -import org.gluu.util.properties.FileConfiguration; - -/** - * Persistence configuration - * - * @author Yuriy Movchan Date: 05/10/2019 - */ -public class PersistenceConfiguration { - - private String fileName; - private FileConfiguration configuration; - private Class entryManagerFactoryType; - private long lastModifiedTime; - - public PersistenceConfiguration() {} - - public PersistenceConfiguration(String fileName, FileConfiguration configuration, - Class entryManagerFactoryType, long lastModifiedTime) { - this.fileName = fileName; - this.configuration = configuration; - this.entryManagerFactoryType = entryManagerFactoryType; - this.lastModifiedTime = lastModifiedTime; - } - - public String getFileName() { - return fileName; - } - - public FileConfiguration getConfiguration() { - return configuration; - } - - public Class getEntryManagerFactoryType() { - return entryManagerFactoryType; - } - - public long getLastModifiedTime() { - return lastModifiedTime; - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/model/ProcessBatchOperation.java b/persistence-core/src/main/java/org/gluu/persist/model/ProcessBatchOperation.java deleted file mode 100644 index 610623f41..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/model/ProcessBatchOperation.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2018, Gluu - */ - -package org.gluu.persist.model; - -/** - * @author Yuriy Movchan Date: 02/07/2018 - */ -public abstract class ProcessBatchOperation implements BatchOperation { - - public boolean collectSearchResult(int size) { - return false; - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/model/SearchScope.java b/persistence-core/src/main/java/org/gluu/persist/model/SearchScope.java deleted file mode 100644 index cc4b6f6d1..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/model/SearchScope.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.model; - -/** - * LDAP search scope - * - * @author Yuriy Movchan Date: 11/18/2016 - */ -public enum SearchScope { - - /** - * A predefined baseObject scope value, which indicates that only the entry - * specified by the base DN should be considered. - */ - BASE, - - /** - * A predefined singleLevel scope value, which indicates that only entries - * that are immediate subordinates of the entry specified by the base DN - * (but not the base entry itself) should be considered. - */ - ONE, - - /** - * A predefined wholeSubtree scope value, which indicates that the base - * entry itself and any subordinate entries (to any depth) should be - * considered. - */ - SUB; - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/model/SortOrder.java b/persistence-core/src/main/java/org/gluu/persist/model/SortOrder.java deleted file mode 100644 index 8f5de4723..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/model/SortOrder.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.model; - -import java.util.HashMap; -import java.util.Map; - -import org.gluu.persist.annotation.AttributeEnum; - -/** - * @author Val Pecaoco - */ -public enum SortOrder implements AttributeEnum { - - ASCENDING("ascending"), - DESCENDING("descending"); - - private String value; - - private static Map MAP_BY_VALUES = new HashMap(); - - static { - for (SortOrder enumType : values()) { - MAP_BY_VALUES.put(enumType.getValue(), enumType); - } - } - - SortOrder(String value) { - this.value = value; - } - - @Override - public String getValue() { - return value; - } - - public static SortOrder getByValue(String value) { - return MAP_BY_VALUES.get(value); - } - - @Override - public SortOrder resolveByValue(String value) { - return getByValue(value); - } -} diff --git a/persistence-core/src/main/java/org/gluu/persist/operation/PersistenceOperationService.java b/persistence-core/src/main/java/org/gluu/persist/operation/PersistenceOperationService.java deleted file mode 100644 index 749109cdc..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/operation/PersistenceOperationService.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2018, Gluu - */ - -package org.gluu.persist.operation; - -/** - * Base interface for Operation Service - * - * @author Yuriy Movchan Date: 06/22/2018 - */ -public interface PersistenceOperationService { - - boolean isConnected(); - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/operation/auth/PasswordDetails.java b/persistence-core/src/main/java/org/gluu/persist/operation/auth/PasswordDetails.java deleted file mode 100644 index b145ddfb2..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/operation/auth/PasswordDetails.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2018, Gluu - */ - -package org.gluu.persist.operation.auth; - -/** - * Store informations about an password - */ -public class PasswordDetails { - private final PasswordEncryptionMethod algorithm; - private final byte[] salt; - private final byte[] password; - - /** - * Creates a new PasswordDetails instance - */ - public PasswordDetails(PasswordEncryptionMethod algorithm, byte[] salt, byte[] password) { - this.algorithm = algorithm; - this.salt = salt; - this.password = password; - } - - /** - * The hash algorithm used to hash the password, null for plain text passwords - */ - public PasswordEncryptionMethod getAlgorithm() { - return algorithm; - } - - /** - * The salt used to hash the password, null if no salt was used - */ - public byte[] getSalt() { - return salt; - } - - /** - * The hashed or plain text password - */ - public byte[] getPassword() { - return password; - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/operation/auth/PasswordEncryptionHelper.java b/persistence-core/src/main/java/org/gluu/persist/operation/auth/PasswordEncryptionHelper.java deleted file mode 100644 index ae892a0ce..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/operation/auth/PasswordEncryptionHelper.java +++ /dev/null @@ -1,482 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2018, Gluu - */ - -package org.gluu.persist.operation.auth; - -import java.security.Key; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.security.spec.KeySpec; -import java.util.Arrays; -import java.util.Base64; - -import javax.crypto.SecretKeyFactory; -import javax.crypto.spec.PBEKeySpec; - -import org.apache.commons.codec.digest.Crypt; -import org.gluu.util.StringHelper; -import org.gluu.util.security.BCrypt; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Perform authentication and password encryption - */ -public final class PasswordEncryptionHelper { - - private static final Logger LOG = LoggerFactory.getLogger(PasswordEncryptionHelper.class); - - private static final byte[] CRYPT_SALT_CHARS = StringHelper.getBytesUtf8("./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); - - private PasswordEncryptionHelper() { - } - - /** - * Get the algorithm from the stored password - */ - public static PasswordEncryptionMethod findAlgorithm(String credentials) { - return findAlgorithm(StringHelper.getBytesUtf8(credentials)); - } - - /** - * Get the algorithm from the stored password - */ - public static PasswordEncryptionMethod findAlgorithm(byte[] credentials) { - if ((credentials == null) || (credentials.length == 0)) { - return null; - } - - if (credentials[0] == '{') { - // Get the algorithm - int pos = 1; - - while (pos < credentials.length) { - if (credentials[pos] == '}') { - break; - } - - pos++; - } - - if (pos < credentials.length) { - if (pos == 1) { - // We don't have an algorithm : return the credentials as is - return null; - } - - String algorithm = StringHelper.toLowerCase(StringHelper.utf8ToString(credentials, 1, pos - 1)); - - // Support for crypt additional encryption algorithms (e.g. - // {crypt}$1$salt$ez2vlPGdaLYkJam5pWs/Y1) - if (credentials.length > pos + 3 && credentials[pos + 1] == '$' && Character.isDigit(credentials[pos + 2])) { - if (credentials[pos + 3] == '$') { - algorithm += StringHelper.utf8ToString(credentials, pos + 1, 3); - } else if (credentials.length > pos + 4 && credentials[pos + 4] == '$') { - algorithm += StringHelper.utf8ToString(credentials, pos + 1, 4); - } - } - - return PasswordEncryptionMethod.getMethod(algorithm); - } else { - // We don't have an algorithm - return null; - } - } else { - // No '{algo}' part - return null; - } - } - - /** - * @see #createStoragePassword(byte[], PasswordEncryptionMethod) - */ - public static String createStoragePassword(String credentials, PasswordEncryptionMethod algorithm) { - byte[] resultBytes = createStoragePassword(StringHelper.getBytesUtf8(credentials), algorithm); - - return StringHelper.utf8ToString(resultBytes); - } - - /** - * Create a hashed password in a format that can be stored in the server. If the - * specified algorithm requires a salt then a random salt of 8 byte size is used - */ - public static byte[] createStoragePassword(byte[] credentials, PasswordEncryptionMethod algorithm) { - // Check plain text password - if (algorithm == null) { - return credentials; - } - - byte[] salt; - - switch (algorithm) { - case HASH_METHOD_SSHA: - case HASH_METHOD_SSHA256: - case HASH_METHOD_SSHA384: - case HASH_METHOD_SSHA512: - case HASH_METHOD_SMD5: - // Use 8 byte salt always except for "crypt" which needs 2 byte salt - salt = new byte[8]; - new SecureRandom().nextBytes(salt); - break; - - case HASH_METHOD_PKCS5S2: - // Use 16 byte salt for PKCS5S2 - salt = new byte[16]; - new SecureRandom().nextBytes(salt); - break; - - case HASH_METHOD_CRYPT: - salt = generateCryptSalt(2); - break; - - case HASH_METHOD_CRYPT_MD5: - case HASH_METHOD_CRYPT_SHA256: - case HASH_METHOD_CRYPT_SHA512: - salt = generateCryptSalt(8); - break; - - case HASH_METHOD_CRYPT_BCRYPT: - case HASH_METHOD_CRYPT_BCRYPT_B: - salt = StringHelper.getBytesUtf8(BCrypt.genSalt()); - break; - - default: - salt = null; - } - - byte[] hashedPassword = encryptPassword(credentials, algorithm, salt); - StringBuilder sb = new StringBuilder(); - - sb.append('{').append(StringHelper.toUpperCase(algorithm.getPrefix())).append('}'); - - if (algorithm == PasswordEncryptionMethod.HASH_METHOD_CRYPT || algorithm == PasswordEncryptionMethod.HASH_METHOD_CRYPT_BCRYPT) { - sb.append(StringHelper.utf8ToString(salt)); - sb.append(StringHelper.utf8ToString(hashedPassword)); - } else if (algorithm == PasswordEncryptionMethod.HASH_METHOD_CRYPT_MD5 || algorithm == PasswordEncryptionMethod.HASH_METHOD_CRYPT_SHA256 - || algorithm == PasswordEncryptionMethod.HASH_METHOD_CRYPT_SHA512) { - sb.append(algorithm.getSubPrefix()); - sb.append(StringHelper.utf8ToString(salt)); - sb.append('$'); - sb.append(StringHelper.utf8ToString(hashedPassword)); - } else if (salt != null) { - byte[] hashedPasswordWithSaltBytes = new byte[hashedPassword.length + salt.length]; - - if (algorithm == PasswordEncryptionMethod.HASH_METHOD_PKCS5S2) { - merge(hashedPasswordWithSaltBytes, salt, hashedPassword); - } else { - merge(hashedPasswordWithSaltBytes, hashedPassword, salt); - } - - sb.append(String.valueOf(Base64.getEncoder().encodeToString(hashedPasswordWithSaltBytes))); - } else { - sb.append(String.valueOf(Base64.getEncoder().encodeToString(hashedPassword))); - } - - return StringHelper.getBytesUtf8(sb.toString()); - } - - /** - * Compare the credentials - */ - public static boolean compareCredentials(String receivedCredentials, String storedCredentials) { - return compareCredentials(StringHelper.getBytesUtf8(receivedCredentials), StringHelper.getBytesUtf8(storedCredentials)); - } - - /** - * Compare the credentials - */ - public static boolean compareCredentials(byte[] receivedCredentials, byte[] storedCredentials) { - PasswordEncryptionMethod algorithm = findAlgorithm(storedCredentials); - - if (algorithm != null) { - // Get the encrypted part of the stored password - PasswordDetails passwordDetails = splitCredentials(storedCredentials); - - // Reuse the saltedPassword information to construct the encrypted password given by the user - byte[] userPassword = encryptPassword(receivedCredentials, passwordDetails.getAlgorithm(), passwordDetails.getSalt()); - - return compareBytes(userPassword, passwordDetails.getPassword()); - } else { - return compareBytes(receivedCredentials, storedCredentials); - } - } - - /** - * Compare two byte[] in a constant time. This is necessary because using an - * Array.equals() is not Timing attack safe ([1], [2] and [3]), a breach that - * can be exploited to break some hashes. - * - * [1] https://en.wikipedia.org/wiki/Timing_attack [2] - * http://rdist.root.org/2009/05/28/timing-attack-in-google-keyczar-library/ [3] - * https://cryptocoding.net/index.php/Coding_rules - */ - private static boolean compareBytes(byte[] provided, byte[] stored) { - if (stored == null) { - return provided == null; - } else if (provided == null) { - return false; - } - - // Now, compare the two passwords, using a constant time method - if (stored.length != provided.length) { - return false; - } - - // Loop on *every* byte in both passwords, and at the end, if one char at least is different, return false - int result = 0; - - for (int i = 0; i < stored.length; i++) { - // If both bytes are equal, xor will be == 0, otherwise it will be != 0 and it will be result - result |= (stored[i] ^ provided[i]); - } - - return result == 0; - } - - /** - * Encrypts the given credentials based on the algorithm name and optional salt - */ - private static byte[] encryptPassword(byte[] credentials, PasswordEncryptionMethod algorithm, byte[] salt) { - switch (algorithm) { - case HASH_METHOD_SHA: - case HASH_METHOD_SSHA: - return digest(PasswordEncryptionMethod.HASH_METHOD_SHA, credentials, salt); - - case HASH_METHOD_SHA256: - case HASH_METHOD_SSHA256: - return digest(PasswordEncryptionMethod.HASH_METHOD_SHA256, credentials, salt); - - case HASH_METHOD_SHA384: - case HASH_METHOD_SSHA384: - return digest(PasswordEncryptionMethod.HASH_METHOD_SHA384, credentials, salt); - - case HASH_METHOD_SHA512: - case HASH_METHOD_SSHA512: - return digest(PasswordEncryptionMethod.HASH_METHOD_SHA512, credentials, salt); - - case HASH_METHOD_MD5: - case HASH_METHOD_SMD5: - return digest(PasswordEncryptionMethod.HASH_METHOD_MD5, credentials, salt); - - case HASH_METHOD_CRYPT: - String saltWithCrypted = Crypt.crypt(StringHelper.utf8ToString(credentials), StringHelper.utf8ToString(salt)); - String crypted = saltWithCrypted.substring(2); - return StringHelper.getBytesUtf8(crypted); - - case HASH_METHOD_CRYPT_MD5: - case HASH_METHOD_CRYPT_SHA256: - case HASH_METHOD_CRYPT_SHA512: - String saltWithCrypted2 = Crypt.crypt(StringHelper.utf8ToString(credentials), algorithm.getSubPrefix() + StringHelper.utf8ToString(salt)); - String crypted2 = saltWithCrypted2.substring(saltWithCrypted2.lastIndexOf('$') + 1); - return StringHelper.getBytesUtf8(crypted2); - - case HASH_METHOD_CRYPT_BCRYPT: - case HASH_METHOD_CRYPT_BCRYPT_B: - String crypted3 = BCrypt.hashPw(StringHelper.utf8ToString(credentials), StringHelper.utf8ToString(salt)); - return StringHelper.getBytesUtf8(crypted3.substring(crypted3.length() - 31)); - - case HASH_METHOD_PKCS5S2: - return generatePbkdf2Hash(credentials, algorithm, salt); - - default: - return credentials; - } - } - - /** - * Compute the hashed password given an algorithm, the credentials and an optional salt. - */ - private static byte[] digest(PasswordEncryptionMethod algorithm, byte[] password, byte[] salt) { - MessageDigest digest; - - try { - digest = MessageDigest.getInstance(algorithm.getAlgorithm()); - } catch (NoSuchAlgorithmException ex) { - return null; - } - - if (salt != null) { - digest.update(password); - digest.update(salt); - return digest.digest(); - } else { - return digest.digest(password); - } - } - - /** - * Decompose the stored password in an algorithm, an eventual salt and the - * password itself. - * - * If the algorithm is SHA, SSHA, MD5 or SMD5, the part following the algorithm - * is base64 encoded - * - * @param credentials - * The byte[] containing the credentials to split - * @return The password - */ - public static PasswordDetails splitCredentials(byte[] credentials) { - PasswordEncryptionMethod algorithm = findAlgorithm(credentials); - - // check plain text password - if (algorithm == null) { - return new PasswordDetails(null, null, credentials); - } - - int algoLength = algorithm.getPrefix().length() + 2; - byte[] password; - - switch (algorithm) { - case HASH_METHOD_MD5: - case HASH_METHOD_SMD5: - return getCredentials(credentials, algoLength, algorithm.getHashLength(), algorithm); - - case HASH_METHOD_SHA: - case HASH_METHOD_SSHA: - return getCredentials(credentials, algoLength, algorithm.getHashLength(), algorithm); - - case HASH_METHOD_SHA256: - case HASH_METHOD_SSHA256: - return getCredentials(credentials, algoLength, algorithm.getHashLength(), algorithm); - - case HASH_METHOD_SHA384: - case HASH_METHOD_SSHA384: - return getCredentials(credentials, algoLength, algorithm.getHashLength(), algorithm); - - case HASH_METHOD_SHA512: - case HASH_METHOD_SSHA512: - return getCredentials(credentials, algoLength, algorithm.getHashLength(), algorithm); - - case HASH_METHOD_PKCS5S2: - return getPbkdf2Credentials(credentials, algoLength, algorithm); - - case HASH_METHOD_CRYPT: - // The password is associated with a salt. Decompose it - // in two parts, no decoding required. - // The salt comes first, not like for SSHA and SMD5, and is 2 bytes long - // The algorithm, salt, and password will be stored into the PasswordDetails - // structure. - byte[] salt = new byte[2]; - password = new byte[credentials.length - salt.length - algoLength]; - split(credentials, algoLength, salt, password); - return new PasswordDetails(algorithm, salt, password); - - case HASH_METHOD_CRYPT_BCRYPT: - case HASH_METHOD_CRYPT_BCRYPT_B: - salt = Arrays.copyOfRange(credentials, algoLength, credentials.length - 31); - password = Arrays.copyOfRange(credentials, credentials.length - 31, credentials.length); - - return new PasswordDetails(algorithm, salt, password); - case HASH_METHOD_CRYPT_MD5: - case HASH_METHOD_CRYPT_SHA256: - case HASH_METHOD_CRYPT_SHA512: - // skip $x$ - algoLength = algoLength + 3; - return getCryptCredentials(credentials, algoLength, algorithm); - - default: - // unknown method - throw new IllegalArgumentException("Unknown hash algorithm " + algorithm); - } - } - - /** - * Compute the credentials - */ - private static PasswordDetails getCredentials(byte[] credentials, int algoLength, int hashLen, PasswordEncryptionMethod algorithm) { - // The password is associated with a salt. Decompose it in two parts, after having decoded the password. - // The salt is at the end of the credentials. - // The algorithm, salt, and password will be stored into the PasswordDetails structure - byte[] passwordAndSalt = Base64.getDecoder().decode(StringHelper.utf8ToString(credentials, algoLength, credentials.length - algoLength)); - - int saltLength = passwordAndSalt.length - hashLen; - byte[] salt = saltLength == 0 ? null : new byte[saltLength]; - byte[] password = new byte[hashLen]; - split(passwordAndSalt, 0, password, salt); - - return new PasswordDetails(algorithm, salt, password); - } - - private static void split(byte[] all, int offset, byte[] left, byte[] right) { - System.arraycopy(all, offset, left, 0, left.length); - if (right != null) { - System.arraycopy(all, offset + left.length, right, 0, right.length); - } - } - - private static void merge(byte[] all, byte[] left, byte[] right) { - System.arraycopy(left, 0, all, 0, left.length); - System.arraycopy(right, 0, all, left.length, right.length); - } - - /** - * Generates a hash based on the - * PKCS5S2 spec - */ - private static byte[] generatePbkdf2Hash(byte[] credentials, PasswordEncryptionMethod algorithm, byte[] salt) { - try { - SecretKeyFactory sk = SecretKeyFactory.getInstance(algorithm.getAlgorithm()); - char[] password = StringHelper.utf8ToString(credentials).toCharArray(); - KeySpec keySpec = new PBEKeySpec(password, salt, 10000, algorithm.getHashLength() * 8); - Key key = sk.generateSecret(keySpec); - return key.getEncoded(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - /** - * Gets the credentials from a PKCS5S2 hash. The salt for PKCS5S2 hash is - * prepended to the password - */ - private static PasswordDetails getPbkdf2Credentials(byte[] credentials, int algoLength, PasswordEncryptionMethod algorithm) { - // The password is associated with a salt. Decompose it in two parts, after having decoded the password. - // The salt is at the *beginning* of the credentials, and is 16 bytes long - // The algorithm, salt, and password will be stored into the PasswordDetails structure - byte[] passwordAndSalt = Base64.getDecoder().decode(StringHelper.utf8ToString(credentials, algoLength, credentials.length - algoLength)); - - int saltLength = passwordAndSalt.length - algorithm.getHashLength(); - byte[] salt = new byte[saltLength]; - byte[] password = new byte[algorithm.getHashLength()]; - - split(passwordAndSalt, 0, salt, password); - - return new PasswordDetails(algorithm, salt, password); - } - - private static byte[] generateCryptSalt(int length) { - byte[] salt = new byte[length]; - SecureRandom sr = new SecureRandom(); - for (int i = 0; i < salt.length; i++) { - salt[i] = CRYPT_SALT_CHARS[sr.nextInt(CRYPT_SALT_CHARS.length)]; - } - - return salt; - } - - private static PasswordDetails getCryptCredentials(byte[] credentials, int algoLength, PasswordEncryptionMethod algorithm) { - // The password is associated with a salt. Decompose it in two parts, no decoding required. - // The salt length is dynamic, between the 2nd and 3rd '$'. - // The algorithm, salt, and password will be stored into the PasswordDetails structure. - - // Skip {crypt}$x$ - int pos = algoLength; - while (pos < credentials.length) { - if (credentials[pos] == '$') { - break; - } - - pos++; - } - - byte[] salt = Arrays.copyOfRange(credentials, algoLength, pos); - byte[] password = Arrays.copyOfRange(credentials, pos + 1, credentials.length); - - return new PasswordDetails(algorithm, salt, password); - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/operation/auth/PasswordEncryptionMethod.java b/persistence-core/src/main/java/org/gluu/persist/operation/auth/PasswordEncryptionMethod.java deleted file mode 100644 index b5292442d..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/operation/auth/PasswordEncryptionMethod.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2018, Gluu - */ -package org.gluu.persist.operation.auth; - -/** - * Password encryption methods - */ -public enum PasswordEncryptionMethod { - /** The SHA encryption method */ - HASH_METHOD_SHA("SHA", "SHA", "sha", 20), - - /** The Salted SHA encryption method */ - HASH_METHOD_SSHA("SSHA", "SHA", "ssha", 20), - - /** The SHA-256 encryption method */ - HASH_METHOD_SHA256("SHA-256", "SHA-256", "sha256", 32), - - /** The salted SHA-256 encryption method */ - HASH_METHOD_SSHA256("SSHA-256", "SHA-256", "ssha256", 32), - - /** The SHA-384 encryption method */ - HASH_METHOD_SHA384("SHA-384", "SHA-384", "sha384", 48), - - /** The salted SHA-384 encryption method */ - HASH_METHOD_SSHA384("SSHA-384", "SHA-384", "ssha384", 48), - - /** The SHA-512 encryption method */ - HASH_METHOD_SHA512("SHA-512", "SHA-512", "sha512", 64), - - /** The salted SHA-512 encryption method */ - HASH_METHOD_SSHA512("SSHA-512", "SHA-512", "ssha512", 64), - - /** The MD5 encryption method */ - HASH_METHOD_MD5("MD5", "MD5", "md5", 16), - - /** The Salter MD5 encryption method */ - HASH_METHOD_SMD5("SMD5", "MD5", "smd5", 16), - - /** The crypt encryption method */ - HASH_METHOD_CRYPT("CRYPT", "CRYPT", "crypt", 11), - - /** The crypt (MD5) encryption method */ - HASH_METHOD_CRYPT_MD5("CRYPT-MD5", "MD5", "crypt", "$1$", 22), - - /** The crypt (SHA-256) encryption method */ - HASH_METHOD_CRYPT_SHA256("CRYPT-SHA-256", "SHA-256", "crypt", "$5$", 43), - - /** The crypt (SHA-512) encryption method */ - HASH_METHOD_CRYPT_SHA512("CRYPT-SHA-512", "SHA-512", "crypt", "$6$", 86), - - /** The BCrypt encryption method */ - HASH_METHOD_CRYPT_BCRYPT("CRYPT-BCRYPT", "BCRYPT", "crypt", "$2a$", 31), - - /** The BCrypt encryption method */ - HASH_METHOD_CRYPT_BCRYPT_B("CRYPT-BCRYPT", "BCRYPT", "bcrypt", "$2b$", 31), - - /** The PBKDF2-based encryption method */ - HASH_METHOD_PKCS5S2("PKCS5S2", "PBKDF2WithHmacSHA1", "PKCS5S2", 32); - - /** The associated name */ - private final String name; - - /** The associated algorithm */ - private final String algorithm; - - /** The associated prefix */ - private final String prefix; - - /** The optional sub-prefix */ - private final String subPrefix; - - /** Hash length */ - private final int hashLength; - - PasswordEncryptionMethod(String name, String algorithm, String prefix, int hashLength) { - this(name, algorithm, prefix, "", hashLength); - } - - PasswordEncryptionMethod(String name, String algorithm, String prefix, String subPrefix, int hashLength) { - this.name = name; - this.algorithm = algorithm; - this.prefix = prefix; - this.subPrefix = subPrefix; - this.hashLength = hashLength; - } - - public String getName() { - return name; - } - - public String getAlgorithm() { - return algorithm; - } - - public String getPrefix() { - return prefix; - } - - public String getSubPrefix() { - return subPrefix; - } - - public final int getHashLength() { - return hashLength; - } - - /** - * Get the associated constant from a string - */ - public static PasswordEncryptionMethod getMethod(String algorithm) { - if (matches(algorithm, HASH_METHOD_SHA)) { - return HASH_METHOD_SHA; - } - - if (matches(algorithm, HASH_METHOD_SSHA)) { - return HASH_METHOD_SSHA; - } - if (matches(algorithm, HASH_METHOD_MD5)) { - return HASH_METHOD_MD5; - } - - if (matches(algorithm, HASH_METHOD_SMD5)) { - return HASH_METHOD_SMD5; - } - - if (matches(algorithm, HASH_METHOD_CRYPT)) { - return HASH_METHOD_CRYPT; - } - - if (matches(algorithm, HASH_METHOD_CRYPT_MD5)) { - return HASH_METHOD_CRYPT_MD5; - } - - if (matches(algorithm, HASH_METHOD_CRYPT_SHA256)) { - return HASH_METHOD_CRYPT_SHA256; - } - - if (matches(algorithm, HASH_METHOD_CRYPT_SHA512)) { - return HASH_METHOD_CRYPT_SHA512; - } - - if (matches(algorithm, HASH_METHOD_CRYPT_BCRYPT)) { - return HASH_METHOD_CRYPT_BCRYPT; - } - - if (matches(algorithm, HASH_METHOD_CRYPT_BCRYPT_B)) { - return HASH_METHOD_CRYPT_BCRYPT_B; - } - - if (matches(algorithm, HASH_METHOD_SHA256)) { - return HASH_METHOD_SHA256; - } - - if (matches(algorithm, HASH_METHOD_SSHA256)) { - return HASH_METHOD_SSHA256; - } - - if (matches(algorithm, HASH_METHOD_SHA384)) { - return HASH_METHOD_SHA384; - } - - if (matches(algorithm, HASH_METHOD_SSHA384)) { - return HASH_METHOD_SSHA384; - } - - if (matches(algorithm, HASH_METHOD_SHA512)) { - return HASH_METHOD_SHA512; - } - - if (matches(algorithm, HASH_METHOD_SSHA512)) { - return HASH_METHOD_SSHA512; - } - - if (matches(algorithm, HASH_METHOD_PKCS5S2)) { - return HASH_METHOD_PKCS5S2; - } - - return null; - } - - private static boolean matches(String algorithm, PasswordEncryptionMethod constant) { - return constant.name.equalsIgnoreCase(algorithm) || (constant.prefix + constant.subPrefix).equalsIgnoreCase(algorithm); - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/reflect/property/BasicPropertyAccessor.java b/persistence-core/src/main/java/org/gluu/persist/reflect/property/BasicPropertyAccessor.java deleted file mode 100644 index 5c2424706..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/reflect/property/BasicPropertyAccessor.java +++ /dev/null @@ -1,269 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.reflect.property; - -import java.beans.Introspector; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import org.gluu.persist.exception.BasePersistenceException; -import org.gluu.persist.exception.PropertyAccessException; -import org.gluu.persist.exception.PropertyNotFoundException; -import org.gluu.persist.reflect.util.ReflectHelper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Accesses property values via a get/set pair, which may be nonpublic. The - * default (and recommended strategy). - */ -public class BasicPropertyAccessor implements PropertyAccessor { - - private static final Logger LOG = LoggerFactory.getLogger(BasicPropertyAccessor.class); - - public static final class BasicSetter implements Setter { - - private static final long serialVersionUID = 1660638549257218450L; - - private Class clazz; - private final transient Method method; - private final String propertyName; - - private BasicSetter(Class clazz, Method method, String propertyName) { - this.clazz = clazz; - this.method = method; - this.propertyName = propertyName; - } - - public void set(Object target, Object value) throws BasePersistenceException { - try { - method.invoke(target, new Object[] {value}); - } catch (NullPointerException npe) { - if (value == null && method.getParameterTypes()[0].isPrimitive()) { - throw new PropertyAccessException(npe, "Null value was assigned to a property of primitive type", true, clazz, - propertyName); - } else { - throw new PropertyAccessException(npe, "NullPointerException occurred while calling", true, clazz, propertyName); - } - } catch (InvocationTargetException ite) { - throw new PropertyAccessException(ite, "Exception occurred inside", true, clazz, propertyName); - } catch (IllegalAccessException iae) { - throw new PropertyAccessException(iae, "IllegalAccessException occurred while calling", true, clazz, propertyName); - // cannot occur - } catch (IllegalArgumentException iae) { - if (value == null && method.getParameterTypes()[0].isPrimitive()) { - throw new PropertyAccessException(iae, "Null value was assigned to a property of primitive type", true, clazz, - propertyName); - } else { - LOG.error("IllegalArgumentException in class: " + clazz.getName() + ", setter method of property: " + propertyName); - LOG.error("expected type: " + method.getParameterTypes()[0].getName() + ", actual value: " - + (value == null ? null : value.getClass().getName())); - throw new PropertyAccessException(iae, "IllegalArgumentException occurred while calling", true, clazz, propertyName); - } - } - } - - public Method getMethod() { - return method; - } - - public String getMethodName() { - return method.getName(); - } - - Object readResolve() { - return createSetter(clazz, propertyName); - } - - @Override - public String toString() { - return "BasicSetter(" + clazz.getName() + '.' + propertyName + ')'; - } - } - - public static final class BasicGetter implements Getter { - - private static final long serialVersionUID = -5736635201315368096L; - - private Class clazz; - private final transient Method method; - private final String propertyName; - - private BasicGetter(Class clazz, Method method, String propertyName) { - this.clazz = clazz; - this.method = method; - this.propertyName = propertyName; - } - - public Object get(Object target) throws BasePersistenceException { - try { - return method.invoke(target, (Object[]) null); - } catch (InvocationTargetException ite) { - throw new PropertyAccessException(ite, "Exception occurred inside", false, clazz, propertyName); - } catch (IllegalAccessException iae) { - throw new PropertyAccessException(iae, "IllegalAccessException occurred while calling", false, clazz, propertyName); - // cannot occur - } catch (IllegalArgumentException iae) { - LOG.error("IllegalArgumentException in class: " + clazz.getName() + ", getter method of property: " + propertyName); - throw new PropertyAccessException(iae, "IllegalArgumentException occurred calling", false, clazz, propertyName); - } - } - - public Class getReturnType() { - return method.getReturnType(); - } - - public Method getMethod() { - return method; - } - - public String getMethodName() { - return method.getName(); - } - - @Override - public String toString() { - return "BasicGetter(" + clazz.getName() + '.' + propertyName + ')'; - } - - Object readResolve() { - return createGetter(clazz, propertyName); - } - } - - public Setter getSetter(Class theClass, String propertyName) throws PropertyNotFoundException { - return createSetter(theClass, propertyName); - } - - private static Setter createSetter(Class theClass, String propertyName) throws PropertyNotFoundException { - BasicSetter result = getSetterOrNull(theClass, propertyName); - if (result == null) { - throw new PropertyNotFoundException("Could not find a setter for property " + propertyName + " in class " + theClass.getName()); - } - return result; - } - - private static BasicSetter getSetterOrNull(Class theClass, String propertyName) { - if ((theClass == Object.class) || (theClass == null)) { - return null; - } - - Method method = setterMethod(theClass, propertyName); - - if (method != null) { - if (!ReflectHelper.isPublic(theClass, method)) { - method.setAccessible(true); - } - - return new BasicSetter(theClass, method, propertyName); - } else { - BasicSetter setter = getSetterOrNull(theClass.getSuperclass(), propertyName); - if (setter == null) { - Class[] interfaces = theClass.getInterfaces(); - for (int i = 0; setter == null && i < interfaces.length; i++) { - setter = getSetterOrNull(interfaces[i], propertyName); - } - } - return setter; - } - - } - - private static Method setterMethod(Class theClass, String propertyName) { - - BasicGetter getter = getGetterOrNull(theClass, propertyName); - Class returnType = (getter == null) ? null : getter.getReturnType(); - - Method[] methods = theClass.getDeclaredMethods(); - Method potentialSetter = null; - for (int i = 0; i < methods.length; i++) { - String methodName = methods[i].getName(); - - if (methods[i].getParameterTypes().length == 1 && methodName.startsWith("set")) { - String testStdMethod = Introspector.decapitalize(methodName.substring(3)); - String testOldMethod = methodName.substring(3); - if (testStdMethod.equals(propertyName) || testOldMethod.equals(propertyName)) { - potentialSetter = methods[i]; - if (returnType == null || methods[i].getParameterTypes()[0].equals(returnType)) { - return potentialSetter; - } - } - } - } - return potentialSetter; - } - - public Getter getGetter(Class theClass, String propertyName) throws PropertyNotFoundException { - return createGetter(theClass, propertyName); - } - - public static Getter createGetter(Class theClass, String propertyName) throws PropertyNotFoundException { - BasicGetter result = getGetterOrNull(theClass, propertyName); - if (result == null) { - throw new PropertyNotFoundException("Could not find a getter for " + propertyName + " in class " + theClass.getName()); - } - return result; - - } - - private static BasicGetter getGetterOrNull(Class theClass, String propertyName) { - if ((theClass == Object.class) || (theClass == null)) { - return null; - } - - Method method = getterMethod(theClass, propertyName); - - if (method != null) { - if (!ReflectHelper.isPublic(theClass, method)) { - method.setAccessible(true); - } - - return new BasicGetter(theClass, method, propertyName); - } else { - BasicGetter getter = getGetterOrNull(theClass.getSuperclass(), propertyName); - if (getter == null) { - Class[] interfaces = theClass.getInterfaces(); - for (int i = 0; getter == null && i < interfaces.length; i++) { - getter = getGetterOrNull(interfaces[i], propertyName); - } - } - return getter; - } - } - - private static Method getterMethod(Class theClass, String propertyName) { - - Method[] methods = theClass.getDeclaredMethods(); - for (int i = 0; i < methods.length; i++) { - // only carry on if the method has no parameters - if (methods[i].getParameterTypes().length == 0) { - String methodName = methods[i].getName(); - - // try "get" - if (methodName.startsWith("get")) { - String testStdMethod = Introspector.decapitalize(methodName.substring(3)); - String testOldMethod = methodName.substring(3); - if (testStdMethod.equals(propertyName) || testOldMethod.equals(propertyName)) { - return methods[i]; - } - - } - - // if not "get", then try "is" - if (methodName.startsWith("is")) { - String testStdMethod = Introspector.decapitalize(methodName.substring(2)); - String testOldMethod = methodName.substring(2); - if (testStdMethod.equals(propertyName) || testOldMethod.equals(propertyName)) { - return methods[i]; - } - } - } - } - return null; - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/reflect/property/BasicPropertyAnnotationResolver.java b/persistence-core/src/main/java/org/gluu/persist/reflect/property/BasicPropertyAnnotationResolver.java deleted file mode 100644 index d2f2c489e..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/reflect/property/BasicPropertyAnnotationResolver.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.reflect.property; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.gluu.persist.exception.PropertyNotFoundException; -import org.gluu.persist.reflect.util.ReflectHelper; -import org.gluu.util.StringHelper; - -/** - * Defines a strategy for accessing class and propery annotations. - * - * @author Yuriy Movchan Date: 10.08.2010 - */ -public class BasicPropertyAnnotationResolver implements PropertyAnnotationResolver { - - public List getClassAnnotations(Class theClass, Class... allowedAnnotations) { - List result = getOnlyAllowedAnntotations(theClass.getAnnotations(), allowedAnnotations); - - Class superClass = theClass.getSuperclass(); - while (ReflectHelper.isNotPrimitiveClass(superClass)) { - result.addAll(getOnlyAllowedAnntotations(superClass.getAnnotations(), allowedAnnotations)); - superClass = superClass.getSuperclass(); - } - - return result; - } - - public List getPropertyAnnotations(Class theClass, String propertyName, Class... allowedAnnotations) - throws PropertyNotFoundException { - if (StringHelper.isEmpty(propertyName)) { - throw new PropertyNotFoundException("Could not find property " + propertyName + " in class " + theClass.getName()); - } - - Class thisClass = theClass; - while (ReflectHelper.isNotPrimitiveClass(thisClass)) { - Field[] fileds = thisClass.getDeclaredFields(); - for (Field filed : fileds) { - if (propertyName.equals(filed.getName())) { - return getOnlyAllowedAnntotations(filed.getAnnotations(), allowedAnnotations); - } - } - thisClass = thisClass.getSuperclass(); - } - - throw new PropertyNotFoundException("Could not find property " + propertyName + " in class " + theClass.getName()); - } - - public Map> getPropertiesAnnotations(Class theClass, Class... allowedAnnotations) { - Map> result = new HashMap>(); - - Class thisClass = theClass; - while (ReflectHelper.isNotPrimitiveClass(thisClass)) { - Field[] fileds = thisClass.getDeclaredFields(); - for (Field filed : fileds) { - List annotations = getOnlyAllowedAnntotations(filed.getAnnotations(), allowedAnnotations); - if ((annotations == null) || (annotations.size() == 0)) { - continue; - } - - result.put(filed.getName(), annotations); - } - thisClass = thisClass.getSuperclass(); - } - - return result; - } - - private List getOnlyAllowedAnntotations(Annotation[] annotations, Class[] allowedAnnotations) { - List result = new ArrayList(); - if (annotations.length == 0) { - return result; - } - - for (Annotation annotation : annotations) { - for (Class allowedAnnotation : allowedAnnotations) { - if (annotation.annotationType().equals(allowedAnnotation)) { - result.add(annotation); - } - } - } - - return result; - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/reflect/property/DirectPropertyAccessor.java b/persistence-core/src/main/java/org/gluu/persist/reflect/property/DirectPropertyAccessor.java deleted file mode 100644 index ad893cea2..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/reflect/property/DirectPropertyAccessor.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.reflect.property; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; - -import org.gluu.persist.exception.BasePersistenceException; -import org.gluu.persist.exception.PropertyAccessException; -import org.gluu.persist.exception.PropertyNotFoundException; -import org.gluu.persist.reflect.util.ReflectHelper; - -/** - * Accesses fields directly. - */ -public class DirectPropertyAccessor implements PropertyAccessor { - - public static final class DirectGetter implements Getter { - - private static final long serialVersionUID = 242538698307476168L; - - private final transient Field field; - private final Class clazz; - private final String name; - - DirectGetter(Field field, Class clazz, String name) { - this.field = field; - this.clazz = clazz; - this.name = name; - } - - public Object get(Object target) throws BasePersistenceException { - try { - return field.get(target); - } catch (Exception e) { - throw new PropertyAccessException(e, "could not get a field value by reflection", false, clazz, name); - } - } - - public Method getMethod() { - return null; - } - - public String getMethodName() { - return null; - } - - public Class getReturnType() { - return field.getType(); - } - - Object readResolve() { - return new DirectGetter(getField(clazz, name), clazz, name); - } - - @Override - public String toString() { - return "DirectGetter(" + clazz.getName() + '.' + name + ')'; - } - } - - public static final class DirectSetter implements Setter { - - private static final long serialVersionUID = 7468445825009849335L; - - private final transient Field field; - private final Class clazz; - private final String name; - - DirectSetter(Field field, Class clazz, String name) { - this.field = field; - this.clazz = clazz; - this.name = name; - } - - public Method getMethod() { - return null; - } - - public String getMethodName() { - return null; - } - - public void set(Object target, Object value) throws BasePersistenceException { - try { - field.set(target, value); - } catch (Exception e) { - if (value == null && field.getType().isPrimitive()) { - throw new PropertyAccessException(e, "Null value was assigned to a property of primitive type", true, clazz, name); - } else { - throw new PropertyAccessException(e, "could not set a field value by reflection", true, clazz, name); - } - } - } - - @Override - public String toString() { - return "DirectSetter(" + clazz.getName() + '.' + name + ')'; - } - - Object readResolve() { - return new DirectSetter(getField(clazz, name), clazz, name); - } - } - - private static Field getField(Class clazz, String name) throws PropertyNotFoundException { - if (clazz == null || clazz == Object.class) { - throw new PropertyNotFoundException("field not found: " + name); - } - Field field; - try { - field = clazz.getDeclaredField(name); - } catch (NoSuchFieldException nsfe) { - field = getField(clazz, clazz.getSuperclass(), name); - } - if (!ReflectHelper.isPublic(clazz, field)) { - field.setAccessible(true); - } - return field; - } - - private static Field getField(Class root, Class clazz, String name) throws PropertyNotFoundException { - if (clazz == null || clazz == Object.class) { - throw new PropertyNotFoundException("field [" + name + "] not found on " + root.getName()); - } - Field field; - try { - field = clazz.getDeclaredField(name); - } catch (NoSuchFieldException nsfe) { - field = getField(root, clazz.getSuperclass(), name); - } - if (!ReflectHelper.isPublic(clazz, field)) { - field.setAccessible(true); - } - return field; - } - - public Getter getGetter(Class theClass, String propertyName) throws PropertyNotFoundException { - return new DirectGetter(getField(theClass, propertyName), theClass, propertyName); - } - - public Setter getSetter(Class theClass, String propertyName) throws PropertyNotFoundException { - return new DirectSetter(getField(theClass, propertyName), theClass, propertyName); - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/reflect/property/Getter.java b/persistence-core/src/main/java/org/gluu/persist/reflect/property/Getter.java deleted file mode 100644 index f6bfa57ce..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/reflect/property/Getter.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.reflect.property; - -import java.io.Serializable; -import java.lang.reflect.Method; - -import org.gluu.persist.exception.BasePersistenceException; - -/** - * Gets values of a particular property - */ -public interface Getter extends Serializable { - /** - * Get the property value from the given instance. - * - * @param owner - * The instance containing the value to be retreived. - * @return The extracted value. - * @throws BasePersistenceException - */ - Object get(Object owner) throws BasePersistenceException; - - /** - * Get the declared Java type - */ - Class getReturnType(); - - /** - * Optional operation (return null) - */ - String getMethodName(); - - /** - * Optional operation (return null) - */ - Method getMethod(); -} diff --git a/persistence-core/src/main/java/org/gluu/persist/reflect/property/PropertyAccessor.java b/persistence-core/src/main/java/org/gluu/persist/reflect/property/PropertyAccessor.java deleted file mode 100644 index 6057aff1c..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/reflect/property/PropertyAccessor.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.reflect.property; - -import org.gluu.persist.exception.PropertyNotFoundException; - -/** - * Abstracts the notion of a "property". Defines a strategy for accessing the - * value of an attribute. - */ -public interface PropertyAccessor { - /** - * Create a "getter" for the named attribute - */ - Getter getGetter(Class theClass, String propertyName) throws PropertyNotFoundException; - - /** - * Create a "setter" for the named attribute - */ - Setter getSetter(Class theClass, String propertyName) throws PropertyNotFoundException; -} diff --git a/persistence-core/src/main/java/org/gluu/persist/reflect/property/PropertyAnnotation.java b/persistence-core/src/main/java/org/gluu/persist/reflect/property/PropertyAnnotation.java deleted file mode 100644 index 7b5375b8f..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/reflect/property/PropertyAnnotation.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.reflect.property; - -import java.io.Serializable; -import java.lang.annotation.Annotation; -import java.util.List; - -/** - * Hold property with their annotations - * - * @author Yuriy Movchan Date: 04.14.2011 - */ -public class PropertyAnnotation implements Comparable, Serializable { - - private static final long serialVersionUID = 4620529664753916995L; - - private final String propertyName; - private final transient List annotations; - - private transient Class parameterType; - - public PropertyAnnotation(String property, List annotations) { - this.propertyName = property; - this.annotations = annotations; - this.parameterType = null; - } - - public String getPropertyName() { - return propertyName; - } - - public List getAnnotations() { - return annotations; - } - - public Class getParameterType() { - return parameterType; - } - - public void setParameterType(Class parameterType) { - this.parameterType = parameterType; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((propertyName == null) ? 0 : propertyName.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - - PropertyAnnotation other = (PropertyAnnotation) obj; - if (propertyName == null) { - if (other.propertyName != null) { - return false; - } - } else if (!propertyName.equals(other.propertyName)) { - return false; - } - - return true; - } - - public int compareTo(PropertyAnnotation other) { - if ((other == null) || (other.getPropertyName() == null)) { - return (propertyName == null) ? 0 : 1; - } else { - return (propertyName == null) ? -1 : propertyName.compareTo(other.getPropertyName()); - } - } - - @Override - public String toString() { - return String.format("PropertyAnnotation [propertyName=%s, annotations=%s]", propertyName, annotations); - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/reflect/property/PropertyAnnotationResolver.java b/persistence-core/src/main/java/org/gluu/persist/reflect/property/PropertyAnnotationResolver.java deleted file mode 100644 index 8ab082cba..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/reflect/property/PropertyAnnotationResolver.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.reflect.property; - -import java.lang.annotation.Annotation; -import java.util.List; -import java.util.Map; - -import org.gluu.persist.exception.PropertyNotFoundException; - -/** - * Defines a strategy for accessing class and propery annotations. - * - * @author Yuriy Movchan Date: 10.08.2010 - */ -public interface PropertyAnnotationResolver { - - /** - * Get list of class annotations - */ - List getClassAnnotations(Class theClass, Class... allowedAnnotations); - - /** - * Get list of property annotations - */ - List getPropertyAnnotations(Class theClass, String propertyName, Class... allowedAnnotations) - throws PropertyNotFoundException; - - /** - * Get map of properties annotations - */ - Map> getPropertiesAnnotations(Class theClass, Class... allowedAnnotations); - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/reflect/property/Setter.java b/persistence-core/src/main/java/org/gluu/persist/reflect/property/Setter.java deleted file mode 100644 index f40487eb6..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/reflect/property/Setter.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.reflect.property; - -import java.io.Serializable; -import java.lang.reflect.Method; - -import org.gluu.persist.exception.BasePersistenceException; - -/** - * Sets values to a particular property. - */ -public interface Setter extends Serializable { - /** - * Set the property value from the given instance - * - * @param target - * The instance upon which to set the given value. - * @param value - * The value to be set on the target. - * @throws BasePersistenceException - */ - void set(Object target, Object value) throws BasePersistenceException; - - /** - * Optional operation (return null) - */ - String getMethodName(); - - /** - * Optional operation (return null) - */ - Method getMethod(); -} diff --git a/persistence-core/src/main/java/org/gluu/persist/reflect/util/ReflectHelper.java b/persistence-core/src/main/java/org/gluu/persist/reflect/util/ReflectHelper.java deleted file mode 100644 index eff05821f..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/reflect/util/ReflectHelper.java +++ /dev/null @@ -1,574 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.reflect.util; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Array; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Member; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import org.gluu.persist.exception.MappingException; -import org.gluu.persist.exception.PropertyNotFoundException; -import org.gluu.persist.reflect.property.BasicPropertyAccessor; -import org.gluu.persist.reflect.property.BasicPropertyAnnotationResolver; -import org.gluu.persist.reflect.property.DirectPropertyAccessor; -import org.gluu.persist.reflect.property.Getter; -import org.gluu.persist.reflect.property.PropertyAccessor; -import org.gluu.persist.reflect.property.Setter; - -/** - * Utility class for various reflection operations. - */ -public final class ReflectHelper { - - private static final PropertyAccessor BASIC_PROPERTY_ACCESSOR = new BasicPropertyAccessor(); - private static final PropertyAccessor DIRECT_PROPERTY_ACCESSOR = new DirectPropertyAccessor(); - - private static final BasicPropertyAnnotationResolver BASIC_PROPERTY_ANNOTATION_RESOLVER = new BasicPropertyAnnotationResolver(); - - public static final Class[] NO_PARAM_SIGNATURE = new Class[0]; - public static final Object[] NO_PARAMS = new Object[0]; - public static final Annotation[] NO_ANNOTATIONS = new Annotation[0]; - - // findbugs: mutable static field should be package protected. In case it needed outside of the class please copy via method - private static final Class[] SINGLE_OBJECT_PARAM_SIGNATURE = new Class[] {Object.class}; - - private static final Method OBJECT_EQUALS; - private static final Method OBJECT_HASHCODE; - - static { - Method eq; - Method hash; - try { - eq = extractEqualsMethod(Object.class); - hash = extractHashCodeMethod(Object.class); - } catch (Exception e) { - throw new RuntimeException("Could not find Object.equals() or Object.hashCode()", e); - } - OBJECT_EQUALS = eq; - OBJECT_HASHCODE = hash; - } - - /** - * Disallow instantiation of ReflectHelper. - */ - private ReflectHelper() { - } - - /** - * Encapsulation of getting hold of a class's {@link Object#equals equals} - * method. - * - * @param clazz - * The class from which to extract the equals method. - * @return The equals method reference - * @throws NoSuchMethodException - * Should indicate an attempt to extract equals method from - * interface. - */ - public static Method extractEqualsMethod(Class clazz) throws NoSuchMethodException { - return clazz.getMethod("equals", SINGLE_OBJECT_PARAM_SIGNATURE); - } - - /** - * Encapsulation of getting hold of a class's {@link Object#hashCode - * hashCode} method. - * - * @param clazz - * The class from which to extract the hashCode method. - * @return The hashCode method reference - * @throws NoSuchMethodException - * Should indicate an attempt to extract hashCode method from - * interface. - */ - public static Method extractHashCodeMethod(Class clazz) throws NoSuchMethodException { - return clazz.getMethod("hashCode", NO_PARAM_SIGNATURE); - } - - /** - * Determine if the given class defines an {@link Object#equals} override. - * - * @param clazz - * The class to check - * @return True if clazz defines an equals override. - */ - public static boolean overridesEquals(Class clazz) { - Method equals; - try { - equals = extractEqualsMethod(clazz); - } catch (NoSuchMethodException nsme) { - return false; // its an interface so we can't really tell - // anything... - } - return !OBJECT_EQUALS.equals(equals); - } - - /** - * Determine if the given class defines a {@link Object#hashCode} override. - * - * @param clazz - * The class to check - * @return True if clazz defines an hashCode override. - */ - public static boolean overridesHashCode(Class clazz) { - Method hashCode; - try { - hashCode = extractHashCodeMethod(clazz); - } catch (NoSuchMethodException nsme) { - return false; // its an interface so we can't really tell - // anything... - } - return !OBJECT_HASHCODE.equals(hashCode); - } - - /** - * Determine if the given class implements or extend the given class. - * - * @param clazz - * The class to check - * @param intf - * The interface to check it against. - * @return True if the class does implement the interface, false otherwise. - */ - public static boolean assignableFrom(Class clazz, Class intf) { - return intf.isAssignableFrom(clazz); - } - - /** - * Perform resolution of a class name. - *

- * Here we first check the context classloader, if one, before delegating to - * {@link Class#forName(String, boolean, ClassLoader)} using the caller's - * classloader - * - * @param name - * The class name - * @param caller - * The class from which this call originated (in order to access - * that class's loader). - * @return The class reference. - * @throws ClassNotFoundException - * From {@link Class#forName(String, boolean, ClassLoader)}. - */ - public static Class classForName(String name, Class caller) throws ClassNotFoundException { - try { - ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); - if (contextClassLoader != null) { - return contextClassLoader.loadClass(name); - } - } catch (Throwable ignore) { - } - return Class.forName(name, true, caller.getClassLoader()); - } - - /** - * Perform resolution of a class name. - *

- * Same as {@link #classForName(String, Class)} except that here we delegate - * to {@link Class#forName(String)} if the context classloader lookup is - * unsuccessful. - * - * @param name - * The class name - * @return The class reference. - * @throws ClassNotFoundException - * From {@link Class#forName(String)}. - */ - public static Class classForName(String name) throws ClassNotFoundException { - try { - ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); - if (contextClassLoader != null) { - return contextClassLoader.loadClass(name); - } - } catch (Throwable ignore) { - } - return Class.forName(name); - } - - /** - * Is this member publicly accessible. - *

- * Short-hand for {@link #isPublic(Class, Member)} passing the member + - * {@link Member#getDeclaringClass()} - * - * @param member - * The member to check - * @return True if the member is publicly accessible. - */ - public static boolean isPublic(Member member) { - return isPublic(member.getDeclaringClass(), member); - } - - /** - * Is this member publicly accessible. - * - * @param clazz - * The class which defines the member - * @param member - * The memeber. - * @return True if the member is publicly accessible, false otherwise. - */ - public static boolean isPublic(Class clazz, Member member) { - return Modifier.isPublic(member.getModifiers()) && Modifier.isPublic(clazz.getModifiers()); - } - - /** - * Attempt to resolve the specified property type through reflection. - * - * @param className - * The name of the class owning the property. - * @param name - * The name of the property. - * @return The type of the property. - * @throws MappingException - * Indicates we were unable to locate the property. - */ - public static Class reflectedPropertyClass(String className, String name) throws MappingException { - try { - Class clazz = ReflectHelper.classForName(className); - return getter(clazz, name).getReturnType(); - } catch (ClassNotFoundException cnfe) { - throw new MappingException("class " + className + " not found while looking for property: " + name, cnfe); - } - } - - private static Getter getter(Class clazz, String name) throws MappingException { - try { - return BASIC_PROPERTY_ACCESSOR.getGetter(clazz, name); - } catch (PropertyNotFoundException pnfe) { - return DIRECT_PROPERTY_ACCESSOR.getGetter(clazz, name); - } - } - - private static Setter setter(Class clazz, String name) throws MappingException { - try { - return BASIC_PROPERTY_ACCESSOR.getSetter(clazz, name); - } catch (PropertyNotFoundException pnfe) { - return DIRECT_PROPERTY_ACCESSOR.getSetter(clazz, name); - } - } - - /** - * Directly retrieve the {@link Getter} reference via the - * {@link BasicPropertyAccessor}. - * - * @param theClass - * The class owning the property - * @param name - * The name of the property - * @return The getter. - * @throws MappingException - * Indicates we were unable to locate the property. - */ - public static Getter getGetter(Class theClass, String name) throws MappingException { - return BASIC_PROPERTY_ACCESSOR.getGetter(theClass, name); - } - - public static Getter getMethodOrPropertyGetter(Class theClass, String name) throws MappingException { - return getter(theClass, name); - } - - /** - * Directly retrieve the {@link Setter} reference via the - * {@link BasicPropertyAccessor}. - * - * @param theClass - * The class owning the property - * @param name - * The name of the property - * @return The setter. - * @throws MappingException - * Indicates we were unable to locate the property. - */ - public static Setter getSetter(Class theClass, String name) throws MappingException { - return BASIC_PROPERTY_ACCESSOR.getSetter(theClass, name); - } - - public static Setter getMethodOrPropertySetter(Class theClass, String name) throws MappingException { - return setter(theClass, name); - } - - /** - * Retrieve the default (no arg) constructor from the given class. - * - * @param clazz - * The class for which to retrieve the default ctor. - * @return The default constructor. - * @throws PropertyNotFoundException - * Indicates there was not publicly accessible, no-arg - * constructor (todo : why PropertyNotFoundException???) - */ - public static Constructor getDefaultConstructor(Class clazz) throws PropertyNotFoundException { - if (isAbstractClass(clazz)) { - return null; - } - - try { - Constructor constructor = clazz.getDeclaredConstructor(NO_PARAM_SIGNATURE); - if (!isPublic(clazz, constructor)) { - constructor.setAccessible(true); - } - return constructor; - } catch (NoSuchMethodException nme) { - throw new PropertyNotFoundException("Object class [" + clazz.getName() + "] must declare a default (no-argument) constructor"); - } - } - - public static T createObjectByDefaultConstructor(Class clazz) throws PropertyNotFoundException, IllegalArgumentException, - InstantiationException, IllegalAccessException, InvocationTargetException { - return getDefaultConstructor(clazz).newInstance(NO_PARAMS); - } - - /** - * Determine if the given class is declared abstract. - * - * @param clazz - * The class to check. - * @return True if the class is abstract, false otherwise. - */ - public static boolean isAbstractClass(Class clazz) { - int modifier = clazz.getModifiers(); - return Modifier.isAbstract(modifier) || Modifier.isInterface(modifier); - } - - /** - * Determine is the given class is declared final. - * - * @param clazz - * The class to check. - * @return True if the class is final, flase otherwise. - */ - public static boolean isFinalClass(Class clazz) { - return Modifier.isFinal(clazz.getModifiers()); - } - - /** - * Retrieve a constructor for the given class, with arguments matching the - * specified Hibernate mapping. - * - * @param clazz - * The class needing instantiation - * @param parameterTypes - * The types representing the required ctor param signature - * @return The matching constructor. - * @throws PropertyNotFoundException - * Indicates we could not locate an appropriate constructor - * (todo : again with PropertyNotFoundException???) - */ - public static Constructor getConstructor(Class clazz, Class... parameterTypes) throws PropertyNotFoundException { - Constructor constructor = null; - try { - constructor = clazz.getConstructor(parameterTypes); - } catch (Exception e) { - throw new PropertyNotFoundException("Object class [" + clazz.getName() + "] must declare constructor with specifid types " - + Arrays.toString(parameterTypes)); - } - - if (constructor != null) { - if (!isPublic(clazz, constructor)) { - constructor.setAccessible(true); - } - return constructor; - } - - throw new PropertyNotFoundException("no appropriate constructor in class: " + clazz.getName()); - } - - public static Method getMethod(Class clazz, Method method) { - try { - return clazz.getMethod(method.getName(), method.getParameterTypes()); - } catch (Exception e) { - return null; - } - } - - public static Annotation getAnnotationByType(List annotations, Class annotationType) { - if (annotations == null) { - return null; - } - - return getAnnotationByType(annotations.toArray(NO_ANNOTATIONS), annotationType); - } - - public static Annotation getAnnotationByType(Annotation[] annotations, Class annotationType) { - - for (Annotation annotation : annotations) { - if (annotation.annotationType().equals(annotationType)) { - return annotation; - } - } - - return null; - } - - public static String getPropertyNameByType(Map> propertiesAnnotations, Class annotationType) { - for (Entry> propertiesAnnotation : propertiesAnnotations.entrySet()) { - Annotation annotation = getAnnotationByType(propertiesAnnotation.getValue(), annotationType); - if (annotation != null) { - return propertiesAnnotation.getKey(); - } - } - - return null; - } - - public static boolean isNotPrimitiveClass(Class theClass) { - return !((theClass == null) || theClass.equals(Object.class) || theClass.isPrimitive()); - } - - public static List getClassAnnotations(Class theClass, Class... allowedAnnotations) throws PropertyNotFoundException { - return BASIC_PROPERTY_ANNOTATION_RESOLVER.getClassAnnotations(theClass, allowedAnnotations); - } - - public static List getPropertyAnnotations(Class theClass, String propertyName, Class... allowedAnnotations) - throws PropertyNotFoundException { - return BASIC_PROPERTY_ANNOTATION_RESOLVER.getPropertyAnnotations(theClass, propertyName, allowedAnnotations); - } - - public static Map> getPropertiesAnnotations(Class theClass, Class... allowedAnnotations) { - return BASIC_PROPERTY_ANNOTATION_RESOLVER.getPropertiesAnnotations(theClass, allowedAnnotations); - } - - public static Class getListType(Getter getter) { - if (getter == null) { - return null; - } - - Type type = getter.getMethod().getGenericReturnType(); - if (assignableFrom(type.getClass(), ParameterizedType.class)) { - return (Class) (((ParameterizedType) type).getActualTypeArguments())[0]; - } else { - return null; - } - } - - public static Class getListType(Setter setter) { - if (setter == null) { - return null; - } - - Type[] types = setter.getMethod().getGenericParameterTypes(); - if (assignableFrom(ParameterizedType[].class, types.getClass())) { - return (Class) ((ParameterizedType) types[0]).getActualTypeArguments()[0]; - } else { - return null; - } - } - - public static Class getSetterType(Setter setter) { - if (setter == null) { - return null; - } - - return setter.getMethod().getParameterTypes()[0]; - } - - public static Object getValue(Object object, String name) throws MappingException { - if (object == null) { - throw new MappingException("Input value is null"); - } - - Getter getter = BASIC_PROPERTY_ACCESSOR.getGetter(object.getClass(), name); - - return getter.get(object); - } - - public static Object createArray(Class clazz, int length) { - if (clazz.isArray()) { - return Array.newInstance(clazz.getComponentType(), length); - } else { - return Array.newInstance(clazz, length); - } - } - - public static Object getPropertyValue(Object entry, Getter[] propertyGetters) { - if ((entry == null) || (propertyGetters.length == 0)) { - return null; - } - - Object curEntry = entry; - for (Getter propertyGetter : propertyGetters) { - if (curEntry == null) { - break; - } - curEntry = propertyGetter.get(curEntry); - } - - return curEntry; - } - - public static void copyObjectPropertyValues(Object fromEntry, Object toEntry, Getter[] propertyGetters, Setter[] propertySetters) { - if ((fromEntry == null) || (toEntry == null) || (propertyGetters.length == 0)) { - return; - } - - if (propertyGetters.length != propertySetters.length) { - throw new MappingException("Invalid numbers of setters specified"); - } - - for (int i = 0; i < propertyGetters.length; i++) { - Object value = propertyGetters[i].get(fromEntry); - propertySetters[i].set(toEntry, value); - } - } - - public static void sumObjectPropertyValues(Object resultEntry, Object entryToAdd, Getter[] propertyGetters, Setter[] propertySetters) { - if ((resultEntry == null) || (entryToAdd == null) || (propertyGetters.length == 0)) { - return; - } - - if (propertyGetters.length != propertySetters.length) { - throw new MappingException("Invalid numbers of setters specified"); - } - - for (int i = 0; i < propertyGetters.length; i++) { - Class returnType = propertyGetters[i].getReturnType(); - Object value1 = propertyGetters[i].get(resultEntry); - Object value2 = propertyGetters[i].get(entryToAdd); - - Object resultValue; - if ((returnType == int.class) || (returnType == Integer.class)) { - Integer num1 = (value1 == null) ? 0 : (Integer) value1; - Integer num2 = (value2 == null) ? 0 : (Integer) value2; - - resultValue = (int) 0 + num1 + num2; - } else if ((returnType == float.class) || (returnType == Float.class)) { - Float num1 = (value1 == null) ? 0 : (Float) value1; - Float num2 = (value2 == null) ? 0 : (Float) value2; - - resultValue = 0.0f + num1 + num2; - } else if ((returnType == double.class) || (returnType == Double.class)) { - Double num1 = (value1 == null) ? 0 : (Double) value1; - Double num2 = (value2 == null) ? 0 : (Double) value2; - - resultValue = 0.0d + num1 + num2; - } else { - throw new MappingException("Invalid return type of method " + propertyGetters[i].getMethodName()); - } - - propertySetters[i].set(resultEntry, resultValue); - } - } - - public static Method getMethod(Class clazz, String methodName, Class[] methodParams) throws NoSuchMethodException { - try { - return clazz.getMethod(methodName, methodParams); - } catch (Exception ex) { - throw new NoSuchMethodException("Method " + methodName + " doesn't exist in class " + clazz); - } - } - -} diff --git a/persistence-core/src/main/java/org/gluu/persist/service/BaseFactoryService.java b/persistence-core/src/main/java/org/gluu/persist/service/BaseFactoryService.java deleted file mode 100644 index 89f4c2b90..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/service/BaseFactoryService.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.gluu.persist.service; - -import org.gluu.persist.PersistenceEntryManagerFactory; -import org.gluu.persist.model.PersistenceConfiguration; -import org.slf4j.Logger; - -public interface BaseFactoryService { - - PersistenceConfiguration loadPersistenceConfiguration(); - - PersistenceConfiguration loadPersistenceConfiguration(String applicationPropertiesFile); - - PersistenceEntryManagerFactory getPersistenceEntryManagerFactory(PersistenceConfiguration persistenceConfiguration); - - PersistenceEntryManagerFactory getPersistenceEntryManagerFactory( - Class persistenceEntryManagerFactoryClass); - - PersistenceEntryManagerFactory getPersistenceEntryManagerFactory(String persistenceType); - - Logger getLog(); - -} \ No newline at end of file diff --git a/persistence-core/src/main/java/org/gluu/persist/watch/DurationUtil.java b/persistence-core/src/main/java/org/gluu/persist/watch/DurationUtil.java deleted file mode 100644 index 0b6a72759..000000000 --- a/persistence-core/src/main/java/org/gluu/persist/watch/DurationUtil.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.gluu.persist.watch; - -import java.time.Duration; -import java.time.Instant; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Simple duration calculator helper - * - * @author Yuriy Movchan Date: 02/07/2019 - */ -public abstract class DurationUtil { - - protected static final Logger log = LoggerFactory.getLogger(DurationUtil.class); - - public Instant now() { - return Instant.now(); - } - - public Duration duration(Instant start) { - Instant end = Instant.now(); - return Duration.between(start, end); - } - - public Duration duration(Instant start, Instant end) { - return Duration.between(start, end); - } - - public abstract void logDebug(String format, Object... arguments); - -} \ No newline at end of file diff --git a/persistence-core/src/main/resources/key-shortcuter-rules.json b/persistence-core/src/main/resources/key-shortcuter-rules.json deleted file mode 100644 index ecfc61812..000000000 --- a/persistence-core/src/main/resources/key-shortcuter-rules.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "prefixes": [ - "gluu", - "oxAuth", - "oxTrust", - "ox" - ], - "replaces": { - "Group": "_g", - "Client": "_c", - "Type": "_t", - "User": "_u", - "Default": "_d", - "Configuration": "Conf", - "Attribute": "Attr", - "Application": "App", - "Request": "Req", - "Response": "Resp", - "Authentication": "Authn", - "Authorization": "Authz", - "Encrypted": "Enc", - "Encryption": "Enc", - "Signing": "Sig", - "Expiration": "Exp", - "Object": "Obj", - "Token": "Tok", - "Deletable": "del", - "description" : "desc", - "uniqueIdentifier": "_id", - "Password": "Pass", - "Address": "Addr", - "Lifetime": "Life" - }, - "exclusions": { - "oxSoftwareVersion": "softwareVer", - "oxTrustFaviconPath": "_trFaviconPath", - "oxAuthFaviconPath": "_auFaviconPath", - "oxTrustLogoPath": "_trLogoPath", - "oxAuthLogoPath": "_auLogoPath", - "oxApplicationType": "application_t", - "oxTrustLocale": "_trLocale", - "oxTrustnickname": "_trNickName", - "oxTrustMiddleName": "_trMiddleName", - "gluuUrl": "_gUrl", - "oxUrl": "oxUrl", - "oxTrustRole": "_trRole", - "oxAuthX509URL": "_auX509URL", - "oxAuthX509PEM": "_auX509PEM", - "oxTrustConfApplication": "_trConfApp", - "gluuStatus": "_gStatus", - "gluuFaviconImage": "_gFaviconImage", - "oxAssociatedClient": "ass_c" - } -} \ No newline at end of file diff --git a/persistence-core/src/test/java/org/gluu/persist/key/impl/KeyShortcuterTest.java b/persistence-core/src/test/java/org/gluu/persist/key/impl/KeyShortcuterTest.java deleted file mode 100644 index e3b50dff7..000000000 --- a/persistence-core/src/test/java/org/gluu/persist/key/impl/KeyShortcuterTest.java +++ /dev/null @@ -1,87 +0,0 @@ -package org.gluu.persist.key.impl; - -import org.testng.annotations.Test; - -import static org.gluu.persist.key.impl.KeyShortcuter.fromShortcut; -import static org.gluu.persist.key.impl.KeyShortcuter.shortcut; -import static org.testng.Assert.assertEquals; - -/** - * @author Yuriy Zabrovarnyy - */ -public class KeyShortcuterTest { - - //@Test - public void prefixDropped() { - assertEquals(shortcut("gluuAttributeName"), "attrName"); - assertEquals(shortcut("gluuAttributeType"), "attr_t"); - assertEquals(shortcut("oxAuthAppType"), "app_t"); - assertEquals(shortcut("oxAuthLogoutSessionRequired"), "logoutSessionRequired"); - assertEquals(shortcut("oxIconUrl"), "iconUrl"); - assertEquals(shortcut("oxTrustActive"), "active"); - - // reverse - assertEquals(fromShortcut("attrName"), "gluuAttributeName"); - assertEquals(fromShortcut("attr_t"), "gluuAttributeType"); - assertEquals(fromShortcut("app_t"), "oxAuthAppType"); - assertEquals(fromShortcut("logoutSessionRequired"), "oxAuthLogoutSessionRequired"); - assertEquals(fromShortcut("iconUrl"), "oxIconUrl"); - assertEquals(fromShortcut("active"), "oxTrustActive"); - } - - //@Test - public void shortcutsWithMarkers() { - assertEquals(shortcut("gluuGroupVisibility"), "_gVisibility"); - assertEquals(shortcut("oxAuthTrustedClient"), "trusted_c"); - assertEquals(shortcut("oxAuthSubjectType"), "subject_t"); - assertEquals(shortcut("uid"), "_uId"); - assertEquals(shortcut("oxAuthUserDN"), "_uDN"); - assertEquals(shortcut("oxAuthDefaultAcrValues"), "_dAcrValues"); - assertEquals(shortcut("uniqueIdentifier"), "_id"); - assertEquals(shortcut("oxId"), "id"); - - // reverse - assertEquals(fromShortcut("_gVisibility"), "gluuGroupVisibility"); - assertEquals(fromShortcut("trusted_c"), "oxAuthTrustedClient"); - assertEquals(fromShortcut("subject_t"), "oxAuthSubjectType"); - assertEquals(fromShortcut("_uId"), "uid"); - assertEquals(fromShortcut("_uDN"), "oxAuthUserDN"); - assertEquals(fromShortcut("_dAcrValues"), "oxAuthDefaultAcrValues"); - assertEquals(fromShortcut("_id"), "uniqueIdentifier"); - assertEquals(fromShortcut("id"), "oxId"); - } - - //@Test - public void shortcutsWithoutMarkers() { - assertEquals(shortcut("oxSmtpConfiguration"), "smtpConf"); - assertEquals(shortcut("oxTrustConfApplication"), "_trConfApp"); - assertEquals(shortcut("oxTrustConfApplication"), "_trConfApp"); // same again by intention - assertEquals(shortcut("oxAuthUserInfoEncryptedResponseAlg"), "_uInfoEncRespAlg"); - assertEquals(shortcut("authnTime"), "authnTime"); - assertEquals(shortcut("oxIDPAuthentication"), "iDPAuthn"); - assertEquals(shortcut("oxAuthSkipAuthorization"), "skipAuthz"); - assertEquals(shortcut("oxAuthTokenEndpointAuthSigningAlg"), "tokEndpointAuthSigAlg"); - assertEquals(shortcut("oxLinkExpirationDate"), "linkExpDate"); - assertEquals(shortcut("oxAuthRequestObjectEncryptionAlg"), "reqObjEncAlg"); - assertEquals(shortcut("tknTyp"), "tok_t"); - assertEquals(shortcut("oxAuthTokenEndpointAuthSigningAlg"), "tokEndpointAuthSigAlg"); - assertEquals(shortcut("del"), "del"); - assertEquals(shortcut("description"), "desc"); - - // reverse - assertEquals(fromShortcut("smtpConf"), "oxSmtpConfiguration"); - assertEquals(fromShortcut("_trConfApp"), "oxTrustConfApplication"); - assertEquals(fromShortcut("_trConfApp"), "oxTrustConfApplication");// same again by intention - assertEquals(fromShortcut("_uInfoEncRespAlg"), "oxAuthUserInfoEncryptedResponseAlg"); - assertEquals(fromShortcut("authnTime"), "authnTime"); - assertEquals(fromShortcut("iDPAuthn"), "oxIDPAuthentication"); - assertEquals(fromShortcut("skipAuthz"), "oxAuthSkipAuthorization"); - assertEquals(fromShortcut("tokEndpointAuthSigAlg"), "oxAuthTokenEndpointAuthSigningAlg"); - assertEquals(fromShortcut("linkExpDate"), "oxLinkExpirationDate"); - assertEquals(fromShortcut("reqObjEncAlg"), "oxAuthRequestObjectEncryptionAlg"); - assertEquals(fromShortcut("tok_t"), "tknTyp"); - assertEquals(fromShortcut("tokEndpointAuthSigAlg"), "oxAuthTokenEndpointAuthSigningAlg"); - assertEquals(fromShortcut("del"), "del"); - assertEquals(fromShortcut("desc"), "description"); - } -} diff --git a/persistence-core/src/test/java/org/gluu/persist/key/impl/dev/KeyShortcuterManualTest.java b/persistence-core/src/test/java/org/gluu/persist/key/impl/dev/KeyShortcuterManualTest.java deleted file mode 100644 index 53bfbfcf5..000000000 --- a/persistence-core/src/test/java/org/gluu/persist/key/impl/dev/KeyShortcuterManualTest.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.gluu.persist.key.impl.dev; - -import java.util.Arrays; - -import org.gluu.persist.key.impl.KeyShortcuter; - -public class KeyShortcuterManualTest { - - - public static void main(String[] args) { - // All - String[] attrs = new String[] { "oxAssociatedClient", "associatedClient", "associatedPerson", "blowfishPassword", "county", "creationDate", "defaultScope", "deployedAppliances", "federationRules", "gluuAddPersonCapability", "gluuAdditionalBandwidth", "gluuAdditionalMemory", "gluuAdditionalUsers", "gluuApplianceDnsServer", "gluuAppliancePollingInterval", "gluuApplianceUpdateRequestList", "gluuApplianceUpdateReuestList", "gluuAttributeViewType", "gluuAttributeEditType", "gluuAttributeName", "gluuAttributeOrigin", "gluuAttributeSystemEditType", "gluuAttributeType", "gluuAttributeUsageType", "gluuBandwidthRX", "gluuBandwidthTX", "gluuCategory", "gluuContainerFederation", "gluuCustomMessage", "gluuDSstatus", "gluuEntityId", "gluuFaviconImage", "gluuFederationHostingEnabled", "gluuFreeDiskSpace", "gluuFreeMemory", "gluuFreeSwap", "gluuHTTPstatus", "gluuGroupCount", "gluuGroupType", "gluuGroupVisibility", "gluuHostname", "gluuInvoiceAmount", "gluuInvoiceDate", "gluuInvoiceLineItemName", "gluuInvoiceNo", "gluuInvoiceNumber", "gluuInvoiceProductNumber", "gluuInvoiceQuantity", "gluuInvoiceStatus", "gluuIpAddress", "gluuIsFederation", "gluuLastUpdate", "gluuLifeRay", "TODO-remove", "gluuLoadAvg", "gluuLogoImage", "gluuManageIdentityPermission", "gluuManagedOrganizations", "gluuManager", "gluuManagerGroup", "gluuMaxLogSize", "gluuOptOuts", "gluuOrgProfileMgt", "gluuOrgShortName", "gluuPaidUntil", "gluuPaymentProcessorTimestamp", "gluuPersonCount", "gluuPrivate", "gluuProStoresUser", "gluuProfileConfiguration", "gluuPublishIdpMetadata", "gluuReleasedAttribute", "gluuResizeInitiated", "gluuRulesAccepted", "gluuSAML1URI", "gluuSAML2URI", "gluuSAMLMetaDataFilter", "gluuSAMLTrustEngine", "gluuSAMLmaxRefreshDelay", "gluuSAMLspMetaDataFN", "gluuSAMLspMetaDataSourceType", "gluuSAMLspMetaDataURL", "gluuSLAManager", "gluuSPTR", "gluuScimEnabled", "gluuShibAssertionsIssued", "gluuShibFailedAuth", "gluuShibSecurityEvents", "gluuShibSuccessfulAuths", "gluuSmtpFromEmailAddress", "gluuSmtpFromName", "gluuSmtpHost", "gluuSmtpPassword", "gluuSmtpPort", "gluuSmtpRequiresAuthentication", "gluuSmtpRequiresSsl", "gluuSmtpUserName", "gluuSpecificRelyingPartyConfig", "gluuSslExpiry", "gluuStatus", "gluuSystemUptime", "gluuTargetRAM", "gluuTempFaviconImage", "gluuThemeColor", "gluuTrustContact", "gluuTrustDeconstruction", "gluuUrl", "gluuVDSenabled", "gluuVDSstatus", "gluuValidationLog", "gluuValidationStatus", "gluuVdsCacheRefreshEnabled", "gluuVdsCacheRefreshLastUpdate", "gluuVdsCacheRefreshLastUpdateCount", "gluuVdsCacheRefreshPollingInterval", "gluuVdsCacheRefreshProblemCount", "gluuWhitePagesEnabled", "gluuWhitePagesListed", "iname", "inum", "inumFN", "literalBinaryValue", "literalValue", "memberOf", "nonProfit", "organizationalOwner", "oxAmHost", "oxAuthClaimName", "oxAuthAppType", "authnTime", "authzCode", "oxAuthClaim", "oxAuthGroupClaims", "oxAuthClientId", "oxAuthClientIdIssuedAt", "oxAuthClientSecret", "oxAuthClientSecretExpiresAt", "oxAuthClientURI", "oxAuthConfDynamic", "oxAuthConfErrors", "oxAuthConfStatic", "oxAuthConfWebKeys", "oxAuthContact", "iat", "oxAuthDefaultAcrValues", "oxAuthDefaultMaxAge", "oxAuthExpiration", "grtId", "grtTyp", "oxAuthIdTokenEncryptedResponseAlg", "oxAuthIdTokenEncryptedResponseEnc", "oxAuthIdTokenSignedResponseAlg", "oxAuthInitiateLoginURI", "oxAuthJwksURI", "oxAuthJwks", "jwtReq", "oxAuthLogoURI", "nnc", "oxSessionState", "oxAuthPermissionGrantedMap", "oxAuthPersistentJWT", "oxAuthPolicyURI", "oxAuthLogoutURI", "oxAuthLogoutSessionRequired", "oxAuthPostLogoutRedirectURI", "oxAuthRedirectURI", "oxAuthRegistrationAccessToken", "oxAuthReleasedScope", "oxAuthRequestObjectSigningAlg", "oxAuthRequestObjectEncryptionAlg", "oxAuthRequestObjectEncryptionEnc", "oxAuthRequestURI", "oxAuthRequireAuthTime", "oxAuthResponseType", "scp", "oxScopeType", "oxAuthSectorIdentifierURI", "oxAuthSignedResponseAlg", "oxAuthSkipAuthorization", "oxAuthSubjectType", "tknCde", "oxAuthTokenEndpointAuthMethod", "oxAuthTokenEndpointAuthSigningAlg", "tknTyp", "oxAuthTosURI", "oxAuthTrustedClient", "oxAuthUmaScope", "oxAuthUserDN", "uid", "oxAuthUserInfoEncryptedResponseAlg", "oxAuthUserInfoEncryptedResponseEnc", "oxAuthExtraConf", "oxAuthX509PEM", "oxAuthX509URL", "oxAuthenticationMode", "oxTrustAuthenticationMode", "oxConfigurationCode", "oxCreationTimestamp", "oxDomain", "oxExternalUid", "oxFaviconImage", "oxGroup", "oxGuid", "oxHost", "oxIDPAuthentication", "oxIconUrl", "oxId", "oxAsJwt", "oxJwt", "oxInvolvedClients", "oxLastAccessTime", "oxLastLogonTime", "oxLinkCreator", "oxLinkExpirationDate", "oxLinkLinktrack", "oxLinkModerated", "oxLinkModerators", "oxLinkPending", "oxLinktrackEnabled", "oxLinktrackLogin", "oxLinktrackPassword", "oxLogViewerConfig", "oxMultiValuedAttribute", "oxName", "oxNameIdType", "oxPolicyRule", "oxUmaPolicyScriptDn", "oxProxConf", "oxProxyAccessToken", "oxProxyClaimMapping", "oxState", "oxCounter", "oxStatus", "oxApplication", "oxDeviceRegistrationConf", "oxDeviceKeyHandle", "oxDeviceHashCode", "oxRequest", "oxRequestId", "oxDeviceData", "oxEnrollmentCode", "oxProxyClientId", "oxProxyScope", "oxProxyToOpClientMapping", "oxPushApplication", "oxPushApplicationConf", "oxPushDeviceConf", "oxRegistrationConfiguration", "oxResource", "oxResourceSetId", "oxRevision", "oxLevel", "oxSCIMCustomAttribute", "oxScript", "oxScriptDn", "oxScriptType", "oxScriptError", "oxSmtpConfiguration", "oxSourceAttribute", "oxTicket", "oxTrustActive", "oxTrustCacheRefreshServerIpAddress", "oxTrustAddresses", "oxTrustConfApplication", "oxTrustConfCacheRefresh", "oxConfApplication", "oxTrustCustAttrB", "oxTrustEmail", "oxTrustEntitlements", "oxTrustExternalId", "oxTrustImsValue", "oxTrustMetaCreated", "oxTrustMetaLastModified", "oxTrustMetaLocation", "oxTrustMetaVersion", "oxTrustNameFormatted", "oxTrustPhoneValue", "oxTrustPhotos", "oxTrustProfileURL", "oxTrustRole", "oxTrustStoreCert", "oxTrustStoreConf", "oxTrustTitle", "oxTrustUserType", "oxTrusthonorificPrefix", "oxTrusthonorificSuffix", "oxTrustx509Certificate", "oxType", "oxUmaPermission", "oxUrl", "oxX509PEM", "oxX509URL", "passwordResetAllowed", "persistentId", "personInum", "primaryKeyAttrName", "primaryKeyValue", "proStoresToken", "programmingLanguage", "prostoresTimestamp", "registrationDate", "role", "scimAuthMode", "scimGroup", "scimStatus", "secondaryKeyAttrName", "secondaryKeyValue", "secretAnswer", "secretQuestion", "softwareVersion", "sourceRelationalXdiStatement", "targetRelationalXdiStatement", "tertiaryKeyAttrName", "tertiaryKeyValue", "transientId", "url", "urn", "x", "xdiStatement", "xri", "middleName", "oxTrustMiddleName", "nickname", "oxTrustnickname", "preferredUsername", "profile", "picture", "photo1", "website", "emailVerified", "gender", "birthdate", "zoneinfo", "timezone", "locale", "oxTrustLocale", "phoneNumberVerified", "address", "updatedAt", "gluuRegExp", "gluuTooltip", "oxModuleProperty", "oxConfigurationProperty", "oxAuthSessionAttribute", "researchAndScholarshipEnabled", "oxStartDate", "oxEndDate", "oxApplicationType", "oxMetricType", "oxData", "chlng", "chlngMth", "oxSectorIdentifier", "oxPersistClientAuthorizations", "oxTrustConfImportPerson", "oxSessionStateId", "ssnId", "oxPasswordExpirationDate", "oxCountInvalidLogin", "gluuIMAPData", "gluuPassportConfiguration", "gluuPassportEnabled", "gluuRadiusEnabled", "gluuSamlEnabled", "oxValidation", "gluuEntityType", "oxPPID", "oxAuthSessionId", "oxCacheConfiguration", "oxLogConfigLocation", "oxIncludeClaimsInIdToken", "oxClaimValues", "oxClaimRedirectURI", "oxAttributes", "userRandomKey", "oxRefreshTokenLifetime", "oxTrustConfAttributeResolver", "oxAuthPermissionGranted", "oxNickName", "oxDeviceNotificationConf", "clms", "oxDisabled", "oxWebKeysSettings", "oxScopeExpression", "oxPreferredMethod", "oxOTPDevices", "oxMobileDevices", "oxdId", "oxAuthAuthorizedOrigins", "oxStrongAuthPolicy", "oxTrustedDevicesInfo", "tknBndCnf", "oxUnlinkedExternalUids", "oxAccessTokenAsJwt", "oxAccessTokenSigningAlg", "oxRegistrationData", "oxAuthenticationData", "oxPublicKeyId", "oxAccessTokenLifetime", "oxSoftwareId", "oxSoftwareVersion", "oxSoftwareStatement", "oxRptAsJwt", "oxCodeChallengeHash", "del", "oxEnabled", "oxAlias", "oxTrustLogoPath", "oxTrustFaviconPath", "oxAuthLogoPath", "oxAuthFaviconPath", "idpLogoPath", "idpFaviconPath", "parent", "classRef", "gluuSmtpServerTrust" }; - - // Token -// String[] attrs = new String[] { "tknTyp", "grtId", "grtTyp", "authzCode", -// "scp", "objectClass", "tknCde", "dn", "del", "uid", "nnc", -// "authnTime", "iat", "oxAuthExpiration", "oxAttributes", "oxAuthClientId", "ssnId" }; - - // Mimimal user -// String[] attrs = new String[] { "cn", "displayName", "dn", "givenName", "gluuStatus", "inum", "mail", "objectClass", "sn", "uid", -// "userPassword", "oxLastLogonTime" }; - - System.out.println("Attrs:\n" + Arrays.toString(attrs)); - System.out.println("\n==============================="); - - int origSize = 0, shortSize = 0, totalDiff = 0; - for(int i = 0; i < attrs.length; i++) { - String name = attrs[i]; - String shortName = KeyShortcuter.shortcut(name); - - int diff = name.length() - shortName.length(); - origSize += name.length(); - shortSize += shortName.length(); - totalDiff += diff; - - System.out.println(String.format("%s -> %s \t\t-> %d", name, shortName, -diff)); - } - - System.out.println(String.format("\nTOTAL: %d - %d \t\t-> %d", origSize, shortSize, -totalDiff)); - } - -} diff --git a/persistence-couchbase-sample/pom.xml b/persistence-couchbase-sample/pom.xml deleted file mode 100644 index f11796480..000000000 --- a/persistence-couchbase-sample/pom.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - 4.0.0 - org.gluu - oxcore-persistence-couchbase-sample - Persistence Couchbase sample - Sample project to show persistence-couchbase functionality - - - org.gluu - oxcore - 4.0.0-SNAPSHOT - - - - ${maven.min-version} - - - - - - src/main/resources - - **/*.json - **/*.xml - **/*.yml - **/*.properties - - - - - - src/test/resources - - **/*.json - **/*.xml - **/*.yml - **/*.properties - - - - - - - - org.gluu - oxcore-persistence-couchbase - ${project.version} - - - org.apache.logging.log4j - log4j-slf4j-impl - - - - - org.gluu - oxcore-persistence-annotation - ${project.version} - - - org.slf4j - slf4j-simple - - - - - org.testng - testng - - - - \ No newline at end of file diff --git a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/CouchbaseCustomMultiValuedTypesSample.java b/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/CouchbaseCustomMultiValuedTypesSample.java deleted file mode 100644 index 4fc320d3d..000000000 --- a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/CouchbaseCustomMultiValuedTypesSample.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.gluu.couchbase; - -import java.util.Arrays; -import java.util.List; - -import org.gluu.couchbase.model.SimpleUser; -import org.gluu.persist.couchbase.impl.CouchbaseEntryManager; -import org.gluu.persist.couchbase.operation.impl.CouchbaseConnectionProvider; -import org.gluu.persist.model.base.CustomObjectAttribute; -import org.gluu.search.filter.Filter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author Yuriy Movchan Date: 09/16/2019 - */ -public final class CouchbaseCustomMultiValuedTypesSample { - - private static final Logger LOG = LoggerFactory.getLogger(CouchbaseConnectionProvider.class); - - private CouchbaseCustomMultiValuedTypesSample() { - } - - public static void main(String[] args) { - // Prepare sample connection details - CouchbaseSampleEntryManager couchbaseSampleEntryManager = new CouchbaseSampleEntryManager(); - - // Create Couchbase entry manager - CouchbaseEntryManager couchbaseEntryManager = couchbaseSampleEntryManager.createCouchbaseEntryManager(); - - // Add dummy user - SimpleUser newUser = new SimpleUser(); - newUser.setDn(String.format("inum=%s,ou=people,o=gluu", System.currentTimeMillis())); - newUser.setUserId("sample_user_" + System.currentTimeMillis()); - newUser.setUserPassword("test"); - newUser.getCustomAttributes().add(new CustomObjectAttribute("streetAddress", Arrays.asList("London", "Texas", "Kiev"))); - newUser.getCustomAttributes().add(new CustomObjectAttribute("test", "test_value")); - newUser.getCustomAttributes().add(new CustomObjectAttribute("fuzzy", "test_value")); - newUser.setNotes(Arrays.asList("note 1", "note 2", "note 3")); - - couchbaseEntryManager.persist(newUser); - - LOG.info("Added User '{}' with uid '{}' and key '{}'", newUser, newUser.getUserId(), newUser.getDn()); - LOG.info("Persisted custom attributes '{}'", newUser.getCustomAttributes()); - - // Find added dummy user - SimpleUser foundUser = couchbaseEntryManager.find(SimpleUser.class, newUser.getDn()); - LOG.info("Found User '{}' with uid '{}' and key '{}'", foundUser, foundUser.getUserId(), foundUser.getDn()); - - LOG.info("Custom attributes '{}'", foundUser.getCustomAttributes()); - - // Update custom attributes - foundUser.setAttributeValues("streetAddress", Arrays.asList("London", "Texas", "Kiev", "Dublin")); - foundUser.setAttributeValues("test", Arrays.asList("test_value_1", "test_value_2", "test_value_3", "test_value_4")); - foundUser.setAttributeValues("fuzzy", Arrays.asList("fuzzy_value_1", "fuzzy_value_2")); - foundUser.setAttributeValue("simple", "simple"); - - CustomObjectAttribute multiValuedSingleValue = new CustomObjectAttribute("multivalued", "multivalued_single_valued"); - multiValuedSingleValue.setMultiValued(true); - foundUser.getCustomAttributes().add(multiValuedSingleValue); - couchbaseEntryManager.merge(foundUser); - LOG.info("Updated custom attributes '{}'", foundUser.getCustomAttributes()); - - // Find updated dummy user - SimpleUser foundUpdatedUser = couchbaseEntryManager.find(SimpleUser.class, newUser.getDn()); - LOG.info("Found User '{}' with uid '{}' and key '{}'", foundUpdatedUser, foundUpdatedUser.getUserId(), foundUpdatedUser.getDn()); - - LOG.info("Cusom attributes '{}'", foundUpdatedUser.getCustomAttributes()); - - Filter filter = Filter.createEqualityFilter(Filter.createLowercaseFilter("givenName"), "jon"); - List foundUpdatedUsers = couchbaseEntryManager.findEntries("o=gluu", SimpleUser.class, filter); - System.out.println(foundUpdatedUsers); - - } - -} diff --git a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/CouchbaseCustomObjectAttributesSample.java b/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/CouchbaseCustomObjectAttributesSample.java deleted file mode 100644 index 5fdea32e8..000000000 --- a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/CouchbaseCustomObjectAttributesSample.java +++ /dev/null @@ -1,78 +0,0 @@ -package org.gluu.couchbase; - -import java.util.Arrays; -import java.util.Date; -import java.util.List; - -import org.gluu.couchbase.model.SimpleUser; -import org.gluu.couchbase.model.UserRole; -import org.gluu.persist.couchbase.impl.CouchbaseEntryManager; -import org.gluu.persist.couchbase.operation.impl.CouchbaseConnectionProvider; -import org.gluu.persist.model.base.CustomObjectAttribute; -import org.gluu.search.filter.Filter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author Yuriy Movchan Date: 09/24/2019 - */ -public final class CouchbaseCustomObjectAttributesSample { - - private static final Logger LOG = LoggerFactory.getLogger(CouchbaseConnectionProvider.class); - - private CouchbaseCustomObjectAttributesSample() { - } - - public static void main(String[] args) { - // Prepare sample connection details - CouchbaseSampleEntryManager couchbaseSampleEntryManager = new CouchbaseSampleEntryManager(); - - // Create Couchbase entry manager - CouchbaseEntryManager couchbaseEntryManager = couchbaseSampleEntryManager.createCouchbaseEntryManager(); - - // Add dummy user - SimpleUser newUser = new SimpleUser(); - newUser.setDn(String.format("inum=%s,ou=people,o=gluu", System.currentTimeMillis())); - newUser.setUserId("sample_user_" + System.currentTimeMillis()); - newUser.setUserPassword("test"); - newUser.getCustomAttributes().add(new CustomObjectAttribute("streetAddress", Arrays.asList("London", "Texas", "Kiev"))); - newUser.getCustomAttributes().add(new CustomObjectAttribute("test", "test_value")); - newUser.getCustomAttributes().add(new CustomObjectAttribute("birthdate", new Date())); - newUser.getCustomAttributes().add(new CustomObjectAttribute("enabled", false)); - newUser.getCustomAttributes().add(new CustomObjectAttribute("age", 18)); - - newUser.setUserRole(UserRole.ADMIN); - newUser.setNotes(Arrays.asList("note 1", "note 2", "note 3")); - - couchbaseEntryManager.persist(newUser); - - LOG.info("Added User '{}' with uid '{}' and key '{}'", newUser, newUser.getUserId(), newUser.getDn()); - - // Find added dummy user - SimpleUser foundUser = couchbaseEntryManager.find(SimpleUser.class, newUser.getDn()); - LOG.info("Found User '{}' with uid '{}' and key '{}'", foundUser, foundUser.getUserId(), foundUser.getDn()); - - LOG.info("Custom attributes '{}'", foundUser.getCustomAttributes()); - for (CustomObjectAttribute customAttribute : foundUser.getCustomAttributes()) { - if (customAttribute.getValue() instanceof Date) { - LOG.info("Found date custom attribute '{}' with value '{}'", customAttribute.getName(), customAttribute.getValue()); - } else if (customAttribute.getValue() instanceof Integer) { - LOG.info("Found integer custom attribute '{}' with value '{}'", customAttribute.getName(), customAttribute.getValue()); - } else if (customAttribute.getValue() instanceof Boolean) { - LOG.info("Found boolean custom attribute '{}' with value '{}'", customAttribute.getName(), customAttribute.getValue()); - } - - } - - // Find added dummy user by numeric attribute - Filter filter = Filter.createGreaterOrEqualFilter("age", 16); - List foundUsers = couchbaseEntryManager.findEntries("ou=people,o=gluu", SimpleUser.class, filter); - if (foundUsers.size() > 0) { - foundUser = foundUsers.get(0); - LOG.info("Found User '{}' by filter '{}' with uid '{}' and key '{}'", foundUser, filter, foundUser, foundUser); - } else { - LOG.error("Can't find User by filter '{}'", filter); - } - } - -} diff --git a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/CouchbaseCustomStringAttributesSample.java b/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/CouchbaseCustomStringAttributesSample.java deleted file mode 100644 index 988fc03d0..000000000 --- a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/CouchbaseCustomStringAttributesSample.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.gluu.couchbase; - -import java.util.Arrays; -import java.util.Date; - -import org.gluu.couchbase.model.SimpleCustomStringUser; -import org.gluu.couchbase.model.SimpleUser; -import org.gluu.couchbase.model.UserRole; -import org.gluu.persist.couchbase.impl.CouchbaseEntryManager; -import org.gluu.persist.couchbase.operation.impl.CouchbaseConnectionProvider; -import org.gluu.persist.model.base.CustomAttribute; -import org.gluu.persist.model.base.CustomObjectAttribute; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author Yuriy Movchan Date: 09/27/2019 - */ -public final class CouchbaseCustomStringAttributesSample { - - private static final Logger LOG = LoggerFactory.getLogger(CouchbaseConnectionProvider.class); - - private CouchbaseCustomStringAttributesSample() { - } - - public static void main(String[] args) { - // Prepare sample connection details - CouchbaseSampleEntryManager couchbaseSampleEntryManager = new CouchbaseSampleEntryManager(); - - // Create Couchbase entry manager - CouchbaseEntryManager couchbaseEntryManager = couchbaseSampleEntryManager.createCouchbaseEntryManager(); - - // Add dummy user - SimpleUser newUser = new SimpleUser(); - newUser.setDn(String.format("inum=%s,ou=people,o=gluu", System.currentTimeMillis())); - newUser.setUserId("sample_user_" + System.currentTimeMillis()); - newUser.setUserPassword("test"); - newUser.getCustomAttributes().add(new CustomObjectAttribute("streetAddress", Arrays.asList("London", "Texas", "Kiev"))); - newUser.getCustomAttributes().add(new CustomObjectAttribute("test", "test_value")); - newUser.getCustomAttributes().add(new CustomObjectAttribute("birthdate", new Date())); - newUser.getCustomAttributes().add(new CustomObjectAttribute("enabled", false)); - newUser.getCustomAttributes().add(new CustomObjectAttribute("age", 18)); - - newUser.setUserRole(UserRole.ADMIN); - newUser.setNotes(Arrays.asList("note 1", "note 2", "note 3")); - - couchbaseEntryManager.persist(newUser); - - LOG.info("Added User '{}' with uid '{}' and key '{}'", newUser, newUser.getUserId(), newUser.getDn()); - - // Find added dummy user but use custom class with String values - SimpleCustomStringUser foundUser = couchbaseEntryManager.find(SimpleCustomStringUser.class, newUser.getDn()); - LOG.info("Found User '{}' with uid '{}' and key '{}'", foundUser, foundUser.getUserId(), foundUser.getDn()); - - LOG.info("Custom attributes '{}'", foundUser.getCustomAttributes()); - for (CustomAttribute customAttribute : foundUser.getCustomAttributes()) { - LOG.info("Found custom attribute '{}' with value '{}'", customAttribute.getName(), customAttribute.getValue()); - } - } - -} diff --git a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/CouchbaseSample.java b/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/CouchbaseSample.java deleted file mode 100644 index b1dce2ca6..000000000 --- a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/CouchbaseSample.java +++ /dev/null @@ -1,118 +0,0 @@ -package org.gluu.couchbase; - -import java.util.Arrays; -import java.util.List; - -import org.gluu.couchbase.model.SimpleAttribute; -import org.gluu.couchbase.model.SimpleGrant; -import org.gluu.couchbase.model.SimpleSession; -import org.gluu.couchbase.model.SimpleUser; -import org.gluu.persist.couchbase.impl.CouchbaseEntryManager; -import org.gluu.persist.couchbase.operation.impl.CouchbaseConnectionProvider; -import org.gluu.persist.model.PagedResult; -import org.gluu.persist.model.SearchScope; -import org.gluu.persist.model.SortOrder; -import org.gluu.persist.model.base.CustomAttribute; -import org.gluu.persist.model.base.CustomObjectAttribute; -import org.gluu.search.filter.Filter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author Yuriy Movchan Date: 11/03/2016 - */ -public final class CouchbaseSample { - - private static final Logger LOG = LoggerFactory.getLogger(CouchbaseConnectionProvider.class); - - private CouchbaseSample() { - } - - public static void main(String[] args) { - // Prepare sample connection details - CouchbaseSampleEntryManager couchbaseSampleEntryManager = new CouchbaseSampleEntryManager(); - - // Create Couchbase entry manager - CouchbaseEntryManager couchbaseEntryManager = couchbaseSampleEntryManager.createCouchbaseEntryManager(); - - SimpleUser newUser = new SimpleUser(); - newUser.setDn(String.format("inum=%s,ou=people,o=gluu", System.currentTimeMillis())); - newUser.setUserId("sample_user_" + System.currentTimeMillis()); - newUser.setUserPassword("test"); - newUser.getCustomAttributes().add(new CustomObjectAttribute("streetAddress", Arrays.asList("London", "Texas", "Kiev"))); - newUser.getCustomAttributes().add(new CustomObjectAttribute("test", "test_value")); - couchbaseEntryManager.persist(newUser); - -// SimpleUser dummyUser = couchbaseEntryManager.find(SimpleUser.class, "inum=test,o=test,o=gluu"); -// LOG.info("Dummy User '{}'", dummyUser); - - // Find all users which have specified object classes defined in SimpleUser - List users = couchbaseEntryManager.findEntries("o=@!5304.5F36.0E64.E1AC!0001!179C.62D7,o=gluu", SimpleUser.class, null); - for (SimpleUser user : users) { - LOG.info("User with uid: '{}' with DN: '{}'", user.getUserId(), user.getDn()); - } - - if (users.size() > 0) { - // Add attribute "streetAddress" to first user - SimpleUser user = users.get(3); - LOG.info("Updating: " + user.getUserId()); - - String[] values = new String[] { "Somewhere: " + System.currentTimeMillis(), "Somewhere2: " + System.currentTimeMillis() }; - user.getCustomAttributes().add(new CustomObjectAttribute("streetAddress", Arrays.asList(values))); - user.getCustomAttributes().add(new CustomObjectAttribute("test", "test_value")); - user.getCustomAttributes().add(new CustomObjectAttribute("test2", "test_value2")); - user.getCustomAttributes().add(new CustomObjectAttribute("test3", "test_value3")); - user.setUserId("user1"); - user.setUserPassword("test"); - - couchbaseEntryManager.merge(user); - } - - for (SimpleUser user : users) { - boolean result1 = couchbaseEntryManager.authenticate(user.getDn(), "test"); - boolean result2 = couchbaseEntryManager.authenticate("ou=people,o=gluu", user.getUserId(), "test"); - System.out.println("authetication result: " + result1 + ", " + result2); - } - - Filter filter = Filter.createEqualityFilter("gluuStatus", "active"); - List attributes = couchbaseEntryManager.findEntries("o=gluu", SimpleAttribute.class, filter, SearchScope.SUB, null, null, 10, - 0, 0); - for (SimpleAttribute attribute : attributes) { - LOG.info("Attribute with displayName: " + attribute.getCustomAttributes().get(1)); - } - - List sessions = couchbaseEntryManager.findEntries("o=gluu", SimpleSession.class, filter, SearchScope.SUB, null, null, 10, 0, - 0); - LOG.info("Found sessions: " + sessions.size()); - - List grants = couchbaseEntryManager.findEntries("o=gluu", SimpleGrant.class, null, SearchScope.SUB, - new String[] { "grtId" }, null, 1, 0, 0); - LOG.info("Found grants: " + grants.size()); - - try { - PagedResult listViewResponse = couchbaseEntryManager.findPagedEntries("o=gluu", SimpleUser.class, null, - new String[] { "uid", "displayName", "gluuStatus" }, "uid", SortOrder.ASCENDING, 0, 6, 4); - - LOG.info("Found persons: " + listViewResponse.getEntriesCount() + ", total persons: " + listViewResponse.getTotalEntriesCount()); - for (SimpleUser user : listViewResponse.getEntries()) { - System.out.println(user.getUserId()); - } - } catch (Exception ex) { - LOG.info("Failed to search", ex); - } - - try { - PagedResult listViewResponse = couchbaseEntryManager.findPagedEntries("o=gluu", SimpleUser.class, null, - new String[] { "uid", "displayName", "gluuStatus" }, "uid", SortOrder.DESCENDING, 0, 6, 4); - - LOG.info("Found persons: " + listViewResponse.getEntriesCount() + ", total persons: " + listViewResponse.getTotalEntriesCount()); - for (SimpleUser user : listViewResponse.getEntries()) { - System.out.println(user.getUserId()); - } - } catch (Exception ex) { - LOG.info("Failed to search", ex); - } - - } - -} diff --git a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/CouchbaseSampleBatchJob.java b/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/CouchbaseSampleBatchJob.java deleted file mode 100644 index 2472e9273..000000000 --- a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/CouchbaseSampleBatchJob.java +++ /dev/null @@ -1,150 +0,0 @@ -package org.gluu.couchbase; - -import java.util.Arrays; -import java.util.Calendar; -import java.util.Date; -import java.util.List; - -import org.apache.log4j.Logger; -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.status.StatusLogger; -import org.gluu.couchbase.model.SimpleClient; -import org.gluu.couchbase.model.SimpleSession; -import org.gluu.couchbase.model.SimpleTokenCouchbase; -import org.gluu.log.LoggingHelper; -import org.gluu.persist.couchbase.impl.CouchbaseEntryManager; -import org.gluu.persist.exception.EntryPersistenceException; -import org.gluu.persist.model.BatchOperation; -import org.gluu.persist.model.DefaultBatchOperation; -import org.gluu.persist.model.ProcessBatchOperation; -import org.gluu.persist.model.SearchScope; -import org.gluu.persist.model.base.CustomAttribute; -import org.gluu.search.filter.Filter; - -/** - * Created by eugeniuparvan on 1/12/17. - */ -public final class CouchbaseSampleBatchJob { - private static final Logger LOG; - - static { - StatusLogger.getLogger().setLevel(Level.OFF); - LoggingHelper.configureConsoleAppender(); - LOG = Logger.getLogger(CouchbaseSample.class); - } - - private CouchbaseSampleBatchJob() { } - - public static void main(String[] args) { - // Prepare sample connection details - CouchbaseSampleEntryManager couchbaseSampleEntryManager = new CouchbaseSampleEntryManager(); - - // Create Couchbase entry manager - final CouchbaseEntryManager couchbaseEntryManager = couchbaseSampleEntryManager.createCouchbaseEntryManager(); - - BatchOperation tokenCouchbaseBatchOperation = new ProcessBatchOperation() { - private int processedCount = 0; - - @Override - public void performAction(List objects) { - for (SimpleTokenCouchbase simpleTokenCouchbase : objects) { - try { - CustomAttribute customAttribute = getUpdatedAttribute(couchbaseEntryManager, simpleTokenCouchbase.getDn(), "oxAuthExpiration", - simpleTokenCouchbase.getAttribute("oxAuthExpiration")); - simpleTokenCouchbase.setCustomAttributes(Arrays.asList(new CustomAttribute[] {customAttribute})); - couchbaseEntryManager.merge(simpleTokenCouchbase); - processedCount++; - } catch (EntryPersistenceException ex) { - LOG.error("Failed to update entry", ex); - } - } - - LOG.info("Total processed: " + processedCount); - } - }; - - final Filter filter1 = Filter.createPresenceFilter("oxAuthExpiration"); - couchbaseEntryManager.findEntries("o=gluu", SimpleTokenCouchbase.class, filter1, SearchScope.SUB, new String[] {"oxAuthExpiration"}, - tokenCouchbaseBatchOperation, 0, 0, 100); - - BatchOperation sessionBatchOperation = new ProcessBatchOperation() { - private int processedCount = 0; - - @Override - public void performAction(List objects) { - for (SimpleSession simpleSession : objects) { - try { - CustomAttribute customAttribute = getUpdatedAttribute(couchbaseEntryManager, simpleSession.getDn(), "oxLastAccessTime", - simpleSession.getAttribute("oxLastAccessTime")); - simpleSession.setCustomAttributes(Arrays.asList(new CustomAttribute[] {customAttribute})); - couchbaseEntryManager.merge(simpleSession); - processedCount++; - } catch (EntryPersistenceException ex) { - LOG.error("Failed to update entry", ex); - } - } - - LOG.info("Total processed: " + processedCount); - } - }; - - final Filter filter2 = Filter.createPresenceFilter("oxLastAccessTime"); - couchbaseEntryManager.findEntries("o=gluu", SimpleSession.class, filter2, SearchScope.SUB, new String[] {"oxLastAccessTime"}, - sessionBatchOperation, 0, 0, 100); - - BatchOperation clientBatchOperation = new ProcessBatchOperation() { - private int processedCount = 0; - - @Override - public void performAction(List objects) { - for (SimpleClient simpleClient : objects) { - processedCount++; - } - - LOG.info("Total processed: " + processedCount); - } - }; - - final Filter filter3 = Filter.createPresenceFilter("oxAuthClientSecretExpiresAt"); - List result3 = couchbaseEntryManager.findEntries("o=gluu", SimpleClient.class, filter3, SearchScope.SUB, - new String[] {"oxAuthClientSecretExpiresAt"}, clientBatchOperation, 0, 0, 1000); - - LOG.info("Result count (without collecting results): " + result3.size()); - - BatchOperation clientBatchOperation2 = new DefaultBatchOperation() { - private int processedCount = 0; - - @Override - public void performAction(List objects) { - for (SimpleClient simpleClient : objects) { - processedCount++; - } - - LOG.info("Total processed: " + processedCount); - } - }; - - final Filter filter4 = Filter.createPresenceFilter("oxAuthClientSecretExpiresAt"); - List result4 = couchbaseEntryManager.findEntries("o=gluu", SimpleClient.class, filter4, SearchScope.SUB, - new String[] {"oxAuthClientSecretExpiresAt"}, clientBatchOperation2, 0, 0, 1000); - - LOG.info("Result count (with collecting results): " + result4.size()); - } - - private static CustomAttribute getUpdatedAttribute(CouchbaseEntryManager couchbaseEntryManager, String baseDn, String attributeName, String attributeValue) { - try { - Calendar calendar = Calendar.getInstance(); - Date oxLastAccessTimeDate = new Date(); //TODO: Fix it StaticUtils.decodeGeneralizedTime(attributeValue); - calendar.setTime(oxLastAccessTimeDate); - calendar.add(Calendar.SECOND, -1); - - CustomAttribute customAttribute = new CustomAttribute(); - customAttribute.setName(attributeName); - customAttribute.setValue(couchbaseEntryManager.encodeTime(baseDn, calendar.getTime())); - return customAttribute; - } catch (Exception ex) { - LOG.error("Can't parse attribute", ex); - } - return null; - } -} diff --git a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/CouchbaseSampleDelete.java b/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/CouchbaseSampleDelete.java deleted file mode 100644 index a9f006ddd..000000000 --- a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/CouchbaseSampleDelete.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.gluu.couchbase; - -import java.util.Date; - -import org.gluu.persist.couchbase.impl.CouchbaseEntryManager; -import org.gluu.persist.couchbase.operation.impl.CouchbaseConnectionProvider; -import org.gluu.persist.model.base.DeletableEntity; -import org.gluu.search.filter.Filter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author Yuriy Movchan Date: 11/03/2016 - */ -public final class CouchbaseSampleDelete { - - private static final Logger LOG = LoggerFactory.getLogger(CouchbaseConnectionProvider.class); - - private CouchbaseSampleDelete() { - } - - public static void main(String[] args) { - // Prepare sample connection details - CouchbaseSampleEntryManager couchbaseSampleEntryManager = new CouchbaseSampleEntryManager(); - - // Create Couchbase entry manager - CouchbaseEntryManager couchbaseEntryManager = couchbaseSampleEntryManager.createCouchbaseEntryManager(); - - String baseDn = "ou=cache,o=gluu"; - Filter filter = Filter.createANDFilter( - Filter.createEqualityFilter("del", true), - Filter.createLessOrEqualFilter("oxAuthExpiration", couchbaseEntryManager.encodeTime(baseDn, new Date())) - ); - - int result = couchbaseEntryManager.remove(baseDn, DeletableEntity.class, filter, 100); - System.out.println(result); - } - -} diff --git a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/CouchbaseSampleEntryManager.java b/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/CouchbaseSampleEntryManager.java deleted file mode 100644 index 14a6ec1fa..000000000 --- a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/CouchbaseSampleEntryManager.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.gluu.couchbase; - -import java.util.Properties; - -import org.apache.log4j.Logger; -import org.gluu.persist.couchbase.impl.CouchbaseEntryManager; -import org.gluu.persist.couchbase.impl.CouchbaseEntryManagerFactory; - -/** - * @author Yuriy Movchan - * Date: 01/13/2017 - */ -public class CouchbaseSampleEntryManager { - - private static final Logger LOG = Logger.getLogger(CouchbaseSampleEntryManager.class); - - private Properties getSampleConnectionProperties() { - Properties connectionProperties = new Properties(); - - connectionProperties.put("couchbase.servers", "cb-dev-backend.gluu.org"); - connectionProperties.put("couchbase.auth.userName", "admin"); - connectionProperties.put("couchbase.auth.userPassword", "jun8azar"); -// connectionProperties.put("couchbase.buckets", "gluu"); - connectionProperties.put("couchbase.buckets", "gluu, gluu_user, gluu_token"); - - connectionProperties.put("couchbase.bucket.default", "gluu"); - connectionProperties.put("couchbase.bucket.gluu_user.mapping", "people, groups"); - connectionProperties.put("couchbase.bucket.gluu_token.mapping", "sessions"); - - connectionProperties.put("couchbase.password.encryption.method", "CRYPT-SHA-256"); - - return connectionProperties; - } - - public CouchbaseEntryManager createCouchbaseEntryManager() { - CouchbaseEntryManagerFactory couchbaseEntryManagerFactory = new CouchbaseEntryManagerFactory(); - couchbaseEntryManagerFactory.create(); - Properties connectionProperties = getSampleConnectionProperties(); - - CouchbaseEntryManager couchbaseEntryManager = couchbaseEntryManagerFactory.createEntryManager(connectionProperties); - LOG.debug("Created CouchbaseEntryManager: " + couchbaseEntryManager); - - return couchbaseEntryManager; - } - -} \ No newline at end of file diff --git a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/CouchbaseSampleSimpleSessionSample.java b/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/CouchbaseSampleSimpleSessionSample.java deleted file mode 100644 index 0e98b417f..000000000 --- a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/CouchbaseSampleSimpleSessionSample.java +++ /dev/null @@ -1,92 +0,0 @@ -package org.gluu.couchbase; - -import java.util.Date; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ThreadFactory; - -import org.apache.log4j.Logger; -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.status.StatusLogger; -import org.gluu.couchbase.model.SimpleSessionState; -import org.gluu.log.LoggingHelper; -import org.gluu.persist.couchbase.impl.CouchbaseEntryManager; - -/** - * @author Yuriy Movchan Date: 01/25/2016 - */ -public final class CouchbaseSampleSimpleSessionSample { - - private static final Logger LOG; - - static { - StatusLogger.getLogger().setLevel(Level.OFF); - LoggingHelper.configureConsoleAppender(); - LOG = Logger.getLogger(CouchbaseSampleSimpleSessionSample.class); - } - - private CouchbaseSampleSimpleSessionSample() { - } - - public static void main(String[] args) throws InterruptedException { - // Prepare sample connection details - CouchbaseSampleEntryManager couchbaseSampleEntryManager = new CouchbaseSampleEntryManager(); - final CouchbaseEntryManager couchbaseEntryManager = couchbaseSampleEntryManager.createCouchbaseEntryManager(); - - try { - // Create Couchbase entry manager - String sessionId = "xyzcyzxy-a41a-45ad-8a83-61485dbad561"; - final String sessionDn = "uniqueIdentifier=" + sessionId + ",ou=session,o=gluu"; - final String userDn = - "inum=@!E8F2.853B.1E7B.ACE2!0001!39A4.C163!0000!A8F2.DE1E.D7FB,ou=people,o=gluu"; - - final SimpleSessionState simpleSessionState = new SimpleSessionState(); - simpleSessionState.setDn(sessionDn); - simpleSessionState.setId(sessionId); - simpleSessionState.setLastUsedAt(new Date()); - - couchbaseEntryManager.persist(simpleSessionState); - System.out.println("Persisted"); - - int threadCount = 500; - ExecutorService executorService = Executors.newFixedThreadPool(threadCount, daemonThreadFactory()); - for (int i = 0; i < threadCount; i++) { - final int count = i; - executorService.execute(new Runnable() { - @Override - public void run() { - final SimpleSessionState simpleSessionStateFromCouchbase = couchbaseEntryManager.find(SimpleSessionState.class, sessionDn); - String beforeUserDn = simpleSessionStateFromCouchbase.getUserDn(); - String randomUserDn = count % 2 == 0 ? userDn : ""; - - try { - simpleSessionStateFromCouchbase.setUserDn(randomUserDn); - simpleSessionStateFromCouchbase.setLastUsedAt(new Date()); - couchbaseEntryManager.merge(simpleSessionStateFromCouchbase); - System.out.println("Merged thread: " + count + ", userDn: " + randomUserDn + ", before userDn: " + beforeUserDn); - } catch (Throwable e) { - System.out.println("ERROR !!!, thread: " + count + ", userDn: " + randomUserDn + ", before userDn: " + beforeUserDn - + ", error:" + e.getMessage()); - // e.printStackTrace(); - } - } - }); - } - - Thread.sleep(5000L); - } finally { - couchbaseEntryManager.destroy(); - } - } - - public static ThreadFactory daemonThreadFactory() { - return new ThreadFactory() { - public Thread newThread(Runnable runnable) { - Thread thread = new Thread(runnable); - thread.setDaemon(true); - return thread; - } - }; - } - -} diff --git a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/CouchbaseSampleUserSearchSample.java b/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/CouchbaseSampleUserSearchSample.java deleted file mode 100644 index 3cf0fcd40..000000000 --- a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/CouchbaseSampleUserSearchSample.java +++ /dev/null @@ -1,111 +0,0 @@ -package org.gluu.couchbase; - -import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.atomic.AtomicLong; - -import org.apache.log4j.Logger; -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.status.StatusLogger; -import org.gluu.couchbase.model.SimpleUser; -import org.gluu.log.LoggingHelper; -import org.gluu.persist.couchbase.impl.CouchbaseEntryManager; -import org.gluu.search.filter.Filter; - -/** - * @author Yuriy Movchan Date: 09/18/2019 - */ -public final class CouchbaseSampleUserSearchSample { - - private static final Logger LOG; - - static { - StatusLogger.getLogger().setLevel(Level.OFF); - LoggingHelper.configureConsoleAppender(); - LOG = Logger.getLogger(CouchbaseSampleUserSearchSample.class); - } - - private static AtomicLong successResult = new AtomicLong(0) ; - private static AtomicLong failedResult = new AtomicLong(0) ; - private static AtomicLong errorResult = new AtomicLong(0) ; - private static AtomicLong totalTime = new AtomicLong(0) ; - private static AtomicLong activeCount = new AtomicLong(0) ; - - private CouchbaseSampleUserSearchSample() { - } - - public static void main(String[] args) throws InterruptedException { - // Prepare sample connection details - CouchbaseSampleEntryManager couchbaseSampleEntryManager = new CouchbaseSampleEntryManager(); - final CouchbaseEntryManager couchbaseEntryManager = couchbaseSampleEntryManager.createCouchbaseEntryManager(); - - int countUsers = 1000000; - int threadCount = 200; - int threadIterationCount = 10; - - long totalStart = System.currentTimeMillis(); - try { - ExecutorService executorService = Executors.newFixedThreadPool(threadCount, daemonThreadFactory()); - for (int i = 0; i < threadCount; i++) { - activeCount.incrementAndGet(); - final int count = i; - executorService.execute(new Runnable() { - @Override - public void run() { - long start = System.currentTimeMillis(); - for (int j = 0; j < threadIterationCount; j++) { - long userUid = Math.round(Math.random() * countUsers); - String uid = String.format("user%06d", userUid); - try { - Filter filter = Filter.createEqualityFilter(Filter.createLowercaseFilter("uid"), uid); -// Filter filter = Filter.createEqualityFilter("uid", uid); - List foundUsers = couchbaseEntryManager.findEntries("ou=people,o=gluu", SimpleUser.class, filter); - if (foundUsers.size() > 0) { - successResult.incrementAndGet(); - } else { - LOG.warn("Failed to find user: " + uid); - failedResult.incrementAndGet(); - } - } catch (Throwable e) { - errorResult.incrementAndGet(); - System.out.println("ERROR !!!, thread: " + count + ", uid: " + uid + ", error:" + e.getMessage()); - e.printStackTrace(); - } - } - - long end = System.currentTimeMillis(); - long duration = end - start; - LOG.info("Thread " + count + " execution time: " + duration); - totalTime.addAndGet(duration); - activeCount.decrementAndGet(); - } - }); - } - - while (activeCount.get() != 0) { - Thread.sleep(1000L); - } - } finally { - couchbaseEntryManager.destroy(); - } - long totalEnd = System.currentTimeMillis(); - long duration = totalEnd - totalStart; - - LOG.info("Total execution time: " + duration + " after execution: " + (threadCount * threadIterationCount)); - - System.out.println(String.format("successResult: '%d', failedResult: '%d', errorResult: '%d'", successResult.get(), failedResult.get(), errorResult.get())); - } - - public static ThreadFactory daemonThreadFactory() { - return new ThreadFactory() { - public Thread newThread(Runnable runnable) { - Thread thread = new Thread(runnable); - thread.setDaemon(true); - return thread; - } - }; - } - -} diff --git a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/model/SimpleAttribute.java b/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/model/SimpleAttribute.java deleted file mode 100644 index 3fc8e527e..000000000 --- a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/model/SimpleAttribute.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.couchbase.model; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -import org.gluu.persist.model.base.CustomAttribute; -import org.gluu.persist.annotation.AttributesList; -import org.gluu.persist.annotation.CustomObjectClass; -import org.gluu.persist.annotation.DN; -import org.gluu.persist.annotation.DataEntry; -import org.gluu.persist.annotation.ObjectClass; -import org.gluu.util.StringHelper; - -/** - * @author Yuriy Movchan - * Date: 12/30/2016 - */ -@DataEntry -@ObjectClass(value = "gluuAttribute") -public class SimpleAttribute implements Serializable { - - private static final long serialVersionUID = -1634191420188575733L; - - @DN - private String dn; - - @AttributesList(name = "name", value = "values", sortByName = true) - private List customAttributes = new ArrayList(); - - @CustomObjectClass - private String[] customObjectClasses; - - public String getDn() { - return dn; - } - - public void setDn(String dn) { - this.dn = dn; - } - - public List getCustomAttributes() { - return customAttributes; - } - - public void setCustomAttributes(List customAttributes) { - this.customAttributes = customAttributes; - } - - public String getAttribute(String ldapAttribute) { - String attribute = null; - if (ldapAttribute != null && !ldapAttribute.isEmpty()) { - for (CustomAttribute customAttribute : customAttributes) { - if (customAttribute.getName().equals(ldapAttribute)) { - attribute = customAttribute.getValue(); - break; - } - } - } - - return attribute; - } - - public List getAttributeValues(String ldapAttribute) { - List values = null; - if (ldapAttribute != null && !ldapAttribute.isEmpty()) { - for (CustomAttribute customAttribute : customAttributes) { - if (StringHelper.equalsIgnoreCase(customAttribute.getName(), ldapAttribute)) { - values = customAttribute.getValues(); - break; - } - } - } - - return values; - } - - public String[] getCustomObjectClasses() { - return customObjectClasses; - } - - public void setCustomObjectClasses(String[] customObjectClasses) { - this.customObjectClasses = customObjectClasses; - } - -} diff --git a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/model/SimpleClient.java b/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/model/SimpleClient.java deleted file mode 100644 index 4fe790877..000000000 --- a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/model/SimpleClient.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.couchbase.model; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -import org.gluu.persist.model.base.CustomAttribute; -import org.gluu.persist.annotation.AttributesList; -import org.gluu.persist.annotation.CustomObjectClass; -import org.gluu.persist.annotation.DN; -import org.gluu.persist.annotation.DataEntry; -import org.gluu.persist.annotation.ObjectClass; -import org.gluu.util.StringHelper; - -/** - * @author Yuriy Movchan - * Date: 02/08/2018 - */ -@DataEntry -@ObjectClass(value = "oxAuthClient") -public class SimpleClient implements Serializable { - - private static final long serialVersionUID = -2534191420188575733L; - - @DN - private String dn; - - @AttributesList(name = "name", value = "values", sortByName = true) - private List customAttributes = new ArrayList(); - - @CustomObjectClass - private String[] customObjectClasses; - - public String getDn() { - return dn; - } - - public void setDn(String dn) { - this.dn = dn; - } - - public List getCustomAttributes() { - return customAttributes; - } - - public void setCustomAttributes(List customAttributes) { - this.customAttributes = customAttributes; - } - - public String getAttribute(String ldapAttribute) { - String attribute = null; - if (ldapAttribute != null && !ldapAttribute.isEmpty()) { - for (CustomAttribute customAttribute : customAttributes) { - if (customAttribute.getName().equals(ldapAttribute)) { - attribute = customAttribute.getValue(); - break; - } - } - } - - return attribute; - } - - public List getAttributeValues(String ldapAttribute) { - List values = null; - if (ldapAttribute != null && !ldapAttribute.isEmpty()) { - for (CustomAttribute customAttribute : customAttributes) { - if (StringHelper.equalsIgnoreCase(customAttribute.getName(), ldapAttribute)) { - values = customAttribute.getValues(); - break; - } - } - } - - return values; - } - - public String[] getCustomObjectClasses() { - return customObjectClasses; - } - - public void setCustomObjectClasses(String[] customObjectClasses) { - this.customObjectClasses = customObjectClasses; - } - -} diff --git a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/model/SimpleCustomStringUser.java b/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/model/SimpleCustomStringUser.java deleted file mode 100644 index 38100f04d..000000000 --- a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/model/SimpleCustomStringUser.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.couchbase.model; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -import org.gluu.persist.annotation.AttributeName; -import org.gluu.persist.annotation.AttributesList; -import org.gluu.persist.annotation.CustomObjectClass; -import org.gluu.persist.annotation.DN; -import org.gluu.persist.annotation.DataEntry; -import org.gluu.persist.annotation.ObjectClass; -import org.gluu.persist.model.base.CustomAttribute; -import org.gluu.util.StringHelper; - -/** - * @author Yuriy Movchan - * Date: 11/03/2016 - */ -@DataEntry -@ObjectClass(value = "gluuPerson") -public class SimpleCustomStringUser implements Serializable { - - private static final long serialVersionUID = -1634191420188575733L; - - @DN - private String dn; - - @AttributeName(name = "uid") - private String userId; - - @AttributeName(name = "userPassword") - private String userPassword; - - @AttributeName(name = "role") - private UserRole userRole; - - @AttributeName(name = "notes") - private List notes; - - @AttributesList(name = "name", value = "values", sortByName = true) - private List customAttributes = new ArrayList(); - - @CustomObjectClass - private String[] customObjectClasses; - - public String getDn() { - return dn; - } - - public void setDn(String dn) { - this.dn = dn; - } - - public String getUserId() { - return userId; - } - - public void setUserId(String userId) { - this.userId = userId; - } - - public String getUserPassword() { - return userPassword; - } - - public void setUserPassword(String userPassword) { - this.userPassword = userPassword; - } - - public UserRole getUserRole() { - return userRole; - } - - public void setUserRole(UserRole userRole) { - this.userRole = userRole; - } - - public List getNotes() { - return notes; - } - - public void setNotes(List notes) { - this.notes = notes; - } - - public List getCustomAttributes() { - return customAttributes; - } - - public void setCustomAttributes(List customAttributes) { - this.customAttributes = customAttributes; - } - - public String getAttribute(String attributeName) { - String attribute = null; - if (attributeName != null && !attributeName.isEmpty()) { - for (CustomAttribute customAttribute : customAttributes) { - if (customAttribute.getName().equals(attributeName)) { - attribute = customAttribute.getValue(); - break; - } - } - } - - return attribute; - } - - public List getAttributeValues(String attributeName) { - List values = null; - if (attributeName != null && !attributeName.isEmpty()) { - for (CustomAttribute customAttribute : customAttributes) { - if (StringHelper.equalsIgnoreCase(customAttribute.getName(), attributeName)) { - values = customAttribute.getValues(); - break; - } - } - } - - return values; - } - - public void setAttributeValue(String attributeName, String attributeValue) { - if (attributeName != null && !attributeName.isEmpty()) { - for (CustomAttribute customAttribute : customAttributes) { - if (StringHelper.equalsIgnoreCase(customAttribute.getName(), attributeName)) { - customAttribute.setValue(attributeValue); - return; - } - } - customAttributes.add(new CustomAttribute(attributeName, attributeValue)); - } - } - - public void setAttributeValues(String attributeName, List attributeValues) { - if (attributeName != null && !attributeName.isEmpty()) { - for (CustomAttribute customAttribute : customAttributes) { - if (StringHelper.equalsIgnoreCase(customAttribute.getName(), attributeName)) { - customAttribute.setValues(attributeValues); - return; - } - } - customAttributes.add(new CustomAttribute(attributeName, attributeValues)); - } - } - - public String[] getCustomObjectClasses() { - return customObjectClasses; - } - - public void setCustomObjectClasses(String[] customObjectClasses) { - this.customObjectClasses = customObjectClasses; - } - -} diff --git a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/model/SimpleGrant.java b/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/model/SimpleGrant.java deleted file mode 100644 index f0c5c9830..000000000 --- a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/model/SimpleGrant.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.couchbase.model; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -import org.gluu.persist.model.base.CustomAttribute; -import org.gluu.persist.annotation.AttributesList; -import org.gluu.persist.annotation.CustomObjectClass; -import org.gluu.persist.annotation.DN; -import org.gluu.persist.annotation.DataEntry; -import org.gluu.persist.annotation.ObjectClass; -import org.gluu.util.StringHelper; - -/** - * @author Yuriy Movchan - * Date: 12/30/2016 - */ -@DataEntry -@ObjectClass(value = "oxAuthGrant") -public class SimpleGrant implements Serializable { - - private static final long serialVersionUID = -1234191420188575733L; - - @DN - private String dn; - - @AttributesList(name = "name", value = "values", sortByName = true) - private List customAttributes = new ArrayList(); - - @CustomObjectClass - private String[] customObjectClasses; - - public String getDn() { - return dn; - } - - public void setDn(String dn) { - this.dn = dn; - } - - public List getCustomAttributes() { - return customAttributes; - } - - public void setCustomAttributes(List customAttributes) { - this.customAttributes = customAttributes; - } - - public String getAttribute(String ldapAttribute) { - String attribute = null; - if (ldapAttribute != null && !ldapAttribute.isEmpty()) { - for (CustomAttribute customAttribute : customAttributes) { - if (customAttribute.getName().equals(ldapAttribute)) { - attribute = customAttribute.getValue(); - break; - } - } - } - - return attribute; - } - - public List getAttributeValues(String ldapAttribute) { - List values = null; - if (ldapAttribute != null && !ldapAttribute.isEmpty()) { - for (CustomAttribute customAttribute : customAttributes) { - if (StringHelper.equalsIgnoreCase(customAttribute.getName(), ldapAttribute)) { - values = customAttribute.getValues(); - break; - } - } - } - - return values; - } - - public String[] getCustomObjectClasses() { - return customObjectClasses; - } - - public void setCustomObjectClasses(String[] customObjectClasses) { - this.customObjectClasses = customObjectClasses; - } - -} diff --git a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/model/SimpleSession.java b/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/model/SimpleSession.java deleted file mode 100644 index a8f717b15..000000000 --- a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/model/SimpleSession.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.couchbase.model; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -import org.gluu.persist.model.base.CustomAttribute; -import org.gluu.persist.annotation.AttributesList; -import org.gluu.persist.annotation.CustomObjectClass; -import org.gluu.persist.annotation.DN; -import org.gluu.persist.annotation.DataEntry; -import org.gluu.persist.annotation.ObjectClass; -import org.gluu.util.StringHelper; - -/** - * @author Yuriy Movchan - * Date: 12/30/2016 - */ -@DataEntry -@ObjectClass(value = "oxAuthSessionId") -public class SimpleSession implements Serializable { - - private static final long serialVersionUID = -1534191420188575733L; - - @DN - private String dn; - - @AttributesList(name = "name", value = "values", sortByName = true) - private List customAttributes = new ArrayList(); - - @CustomObjectClass - private String[] customObjectClasses; - - public String getDn() { - return dn; - } - - public void setDn(String dn) { - this.dn = dn; - } - - public List getCustomAttributes() { - return customAttributes; - } - - public void setCustomAttributes(List customAttributes) { - this.customAttributes = customAttributes; - } - - public String getAttribute(String ldapAttribute) { - String attribute = null; - if (ldapAttribute != null && !ldapAttribute.isEmpty()) { - for (CustomAttribute customAttribute : customAttributes) { - if (customAttribute.getName().equals(ldapAttribute)) { - attribute = customAttribute.getValue(); - break; - } - } - } - - return attribute; - } - - public List getAttributeValues(String ldapAttribute) { - List values = null; - if (ldapAttribute != null && !ldapAttribute.isEmpty()) { - for (CustomAttribute customAttribute : customAttributes) { - if (StringHelper.equalsIgnoreCase(customAttribute.getName(), ldapAttribute)) { - values = customAttribute.getValues(); - break; - } - } - } - - return values; - } - - public String[] getCustomObjectClasses() { - return customObjectClasses; - } - - public void setCustomObjectClasses(String[] customObjectClasses) { - this.customObjectClasses = customObjectClasses; - } - -} diff --git a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/model/SimpleSessionState.java b/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/model/SimpleSessionState.java deleted file mode 100644 index 019157d83..000000000 --- a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/model/SimpleSessionState.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.couchbase.model; - -import java.io.Serializable; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -import javax.persistence.Transient; - -import org.gluu.persist.annotation.AttributeName; -import org.gluu.persist.annotation.DN; -import org.gluu.persist.annotation.DataEntry; -import org.gluu.persist.annotation.JsonObject; -import org.gluu.persist.annotation.ObjectClass; - -/** - * @author Yuriy Zabrovarnyy - * @author Javier Rojas Blum - * @version December 15, 2015 - */ -@DataEntry -@ObjectClass(value = "oxAuthSessionId") -public class SimpleSessionState implements Serializable { - - private static final long serialVersionUID = -237476411915686378L; - - @DN - private String dn; - - @AttributeName(name = "uniqueIdentifier") - private String id; - - @AttributeName(name = "oxLastAccessTime") - private Date lastUsedAt; - - @AttributeName(name = "oxAuthUserDN") - private String userDn; - - @AttributeName(name = "authnTime") - private Date authenticationTime; - - @AttributeName(name = "oxAuthSessionState") - private Boolean permissionGranted; - - @AttributeName(name = "oxAsJwt") - private Boolean isJwt = false; - - @AttributeName(name = "oxJwt") - private String jwt; - - @JsonObject - @AttributeName(name = "oxAuthSessionAttribute") - private Map sessionAttributes; - - @Transient - private transient boolean persisted; - - public String getDn() { - return dn; - } - - public void setDn(String dn) { - this.dn = dn; - } - - public String getJwt() { - return jwt; - } - - public void setJwt(String jwt) { - this.jwt = jwt; - } - - public Boolean getIsJwt() { - return isJwt; - } - - public void setIsJwt(Boolean isJwt) { - this.isJwt = isJwt; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public Date getLastUsedAt() { - return lastUsedAt != null ? new Date(lastUsedAt.getTime()) : null; - } - - public void setLastUsedAt(Date lastUsedAt) { - this.lastUsedAt = lastUsedAt != null ? new Date(lastUsedAt.getTime()) : null; - } - - public String getUserDn() { - return userDn; - } - - public void setUserDn(String userDn) { - this.userDn = userDn != null ? userDn : ""; - } - - public Date getAuthenticationTime() { - return authenticationTime != null ? new Date(authenticationTime.getTime()) : null; - } - - public void setAuthenticationTime(Date authenticationTime) { - this.authenticationTime = authenticationTime != null ? new Date(authenticationTime.getTime()) : null; - } - - public Boolean getPermissionGranted() { - return permissionGranted; - } - - public void setPermissionGranted(Boolean permissionGranted) { - this.permissionGranted = permissionGranted; - } - - public Map getSessionAttributes() { - if (sessionAttributes == null) { - sessionAttributes = new HashMap(); - } - return sessionAttributes; - } - - public void setSessionAttributes(Map sessionAttributes) { - this.sessionAttributes = sessionAttributes; - } - - public boolean isPersisted() { - return persisted; - } - - public void setPersisted(boolean persisted) { - this.persisted = persisted; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - SimpleSessionState id1 = (SimpleSessionState) o; - - return !(id != null ? !id.equals(id1.id) : id1.id != null); - } - - @Override - public int hashCode() { - return id != null ? id.hashCode() : 0; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(); - sb.append("SessionState"); - sb.append(", dn='").append(dn).append('\''); - sb.append(", id='").append(id).append('\''); - sb.append(", isJwt=").append(isJwt); - sb.append(", lastUsedAt=").append(lastUsedAt); - sb.append(", userDn='").append(userDn).append('\''); - sb.append(", authenticationTime=").append(authenticationTime); - sb.append(", permissionGranted=").append(permissionGranted); - sb.append(", sessionAttributes=").append(sessionAttributes); - sb.append(", persisted=").append(persisted); - sb.append('}'); - return sb.toString(); - } - -} diff --git a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/model/SimpleTokenCouchbase.java b/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/model/SimpleTokenCouchbase.java deleted file mode 100644 index da716aabc..000000000 --- a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/model/SimpleTokenCouchbase.java +++ /dev/null @@ -1,81 +0,0 @@ -package org.gluu.couchbase.model; - -import org.gluu.persist.annotation.*; -import org.gluu.persist.model.base.CustomAttribute; -import org.gluu.util.StringHelper; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -/** - * Created by eugeniuparvan on 1/12/17. - */ -@DataEntry -@ObjectClass(value = "token") -public class SimpleTokenCouchbase implements Serializable { - - private static final long serialVersionUID = 6726419630327625172L; - - @AttributesList(name = "name", value = "values", sortByName = true) - private List customAttributes = new ArrayList(); - - @DN - private String dn; - - @CustomObjectClass - private String[] customObjectClasses; - - public String getDn() { - return dn; - } - - public void setDn(String dn) { - this.dn = dn; - } - - public List getCustomAttributes() { - return customAttributes; - } - - public void setCustomAttributes(List customAttributes) { - this.customAttributes = customAttributes; - } - - public String getAttribute(String ldapAttribute) { - String attribute = null; - if (ldapAttribute != null && !ldapAttribute.isEmpty()) { - for (CustomAttribute customAttribute : customAttributes) { - if (customAttribute.getName().equals(ldapAttribute)) { - attribute = customAttribute.getValue(); - break; - } - } - } - - return attribute; - } - - public List getAttributeValues(String ldapAttribute) { - List values = null; - if (ldapAttribute != null && !ldapAttribute.isEmpty()) { - for (CustomAttribute customAttribute : customAttributes) { - if (StringHelper.equalsIgnoreCase(customAttribute.getName(), ldapAttribute)) { - values = customAttribute.getValues(); - break; - } - } - } - - return values; - } - - public String[] getCustomObjectClasses() { - return customObjectClasses; - } - - public void setCustomObjectClasses(String[] customObjectClasses) { - this.customObjectClasses = customObjectClasses; - } - -} diff --git a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/model/SimpleUser.java b/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/model/SimpleUser.java deleted file mode 100644 index e3335278e..000000000 --- a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/model/SimpleUser.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.couchbase.model; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -import org.gluu.persist.annotation.AttributeName; -import org.gluu.persist.annotation.AttributesList; -import org.gluu.persist.annotation.CustomObjectClass; -import org.gluu.persist.annotation.DN; -import org.gluu.persist.annotation.DataEntry; -import org.gluu.persist.annotation.ObjectClass; -import org.gluu.persist.model.base.CustomObjectAttribute; -import org.gluu.util.StringHelper; - -/** - * @author Yuriy Movchan - * Date: 11/03/2016 - */ -@DataEntry -@ObjectClass(value = "gluuPerson") -public class SimpleUser implements Serializable { - - private static final long serialVersionUID = -1634191420188575733L; - - @DN - private String dn; - - @AttributeName(name = "uid") - private String userId; - - @AttributeName(name = "userPassword") - private String userPassword; - - @AttributeName(name = "role") - private UserRole userRole; - - @AttributeName(name = "notes") - private List notes; - - @AttributesList(name = "name", value = "values", multiValued = "multiValued", sortByName = true) - private List customAttributes = new ArrayList(); - - @CustomObjectClass - private String[] customObjectClasses; - - public String getDn() { - return dn; - } - - public void setDn(String dn) { - this.dn = dn; - } - - public String getUserId() { - return userId; - } - - public void setUserId(String userId) { - this.userId = userId; - } - - public String getUserPassword() { - return userPassword; - } - - public void setUserPassword(String userPassword) { - this.userPassword = userPassword; - } - - public UserRole getUserRole() { - return userRole; - } - - public void setUserRole(UserRole userRole) { - this.userRole = userRole; - } - - public List getNotes() { - return notes; - } - - public void setNotes(List notes) { - this.notes = notes; - } - - public List getCustomAttributes() { - return customAttributes; - } - - public void setCustomAttributes(List customAttributes) { - this.customAttributes = customAttributes; - } - - public Object getAttribute(String attributeName) { - Object attribute = null; - if (attributeName != null && !attributeName.isEmpty()) { - for (CustomObjectAttribute customAttribute : customAttributes) { - if (customAttribute.getName().equals(attributeName)) { - attribute = customAttribute.getValue(); - break; - } - } - } - - return attribute; - } - - public List getAttributeValues(String attributeName) { - List values = null; - if (attributeName != null && !attributeName.isEmpty()) { - for (CustomObjectAttribute customAttribute : customAttributes) { - if (StringHelper.equalsIgnoreCase(customAttribute.getName(), attributeName)) { - values = customAttribute.getValues(); - break; - } - } - } - - return values; - } - - public void setAttributeValue(String attributeName, Object attributeValue) { - if (attributeName != null && !attributeName.isEmpty()) { - for (CustomObjectAttribute customAttribute : customAttributes) { - if (StringHelper.equalsIgnoreCase(customAttribute.getName(), attributeName)) { - customAttribute.setValue(attributeValue); - return; - } - } - customAttributes.add(new CustomObjectAttribute(attributeName, attributeValue)); - } - } - - public void setAttributeValues(String attributeName, List attributeValues) { - if (attributeName != null && !attributeName.isEmpty()) { - for (CustomObjectAttribute customAttribute : customAttributes) { - if (StringHelper.equalsIgnoreCase(customAttribute.getName(), attributeName)) { - customAttribute.setValues(attributeValues); - return; - } - } - customAttributes.add(new CustomObjectAttribute(attributeName, attributeValues)); - } - } - - public String[] getCustomObjectClasses() { - return customObjectClasses; - } - - public void setCustomObjectClasses(String[] customObjectClasses) { - this.customObjectClasses = customObjectClasses; - } - -} diff --git a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/model/UserRole.java b/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/model/UserRole.java deleted file mode 100644 index b863d503b..000000000 --- a/persistence-couchbase-sample/src/main/java/org/gluu/couchbase/model/UserRole.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */package org.gluu.couchbase.model; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -import org.gluu.persist.annotation.AttributeEnum; - -/** - * User role - * - * @author Yuriy Movchan Date: 11.03.2010 - */ -public enum UserRole implements AttributeEnum { - - ADMIN("admin"), OWNER("owner"), MANAGER("manager"), USER("user"); - - private String value; - - private static Map mapByValues = new HashMap(); - - static { - for (UserRole enumType : values()) { - mapByValues.put(enumType.getValue(), enumType); - } - } - - private UserRole(String value) { - this.value = value; - } - - public String getValue() { - return value; - } - - public String getRoleName() { - return value; - } - - public String getDisplayName() { - return value; - } - - public static UserRole getByValue(String value) { - return mapByValues.get(value); - } - - public static UserRole[] getByValues(String[] values) { - UserRole[] roles = new UserRole[values.length]; - for (int i = 0; i < values.length; i++) { - roles[i] = getByValue(values[i]); - } - - return roles; - } - - public static boolean equals(UserRole[] roles1, UserRole[] roles2) { - Arrays.sort(roles1); - Arrays.sort(roles2); - return Arrays.equals(roles1, roles2); - } - - public static boolean containsRole(UserRole[] roles, UserRole role) { - if ((roles == null) || (role == null)) { - return false; - } - - for (int i = 0; i < roles.length; i++) { - if (role.equals(roles[i])) { - return true; - } - } - - return false; - } - - public Enum resolveByValue(String value) { - return getByValue(value); - } - - @Override - public String toString() { - return value; - } - -} diff --git a/persistence-couchbase-sample/src/test/java/org/gluu/couchbase/test/ManualCouchbaseEntryManagerTest.java b/persistence-couchbase-sample/src/test/java/org/gluu/couchbase/test/ManualCouchbaseEntryManagerTest.java deleted file mode 100644 index d20899382..000000000 --- a/persistence-couchbase-sample/src/test/java/org/gluu/couchbase/test/ManualCouchbaseEntryManagerTest.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.gluu.couchbase.test; - -import java.io.IOException; -import java.io.InputStream; -import java.util.List; -import java.util.Properties; - -import org.gluu.couchbase.model.SimpleClient; -import org.gluu.persist.couchbase.impl.CouchbaseEntryManager; -import org.gluu.persist.couchbase.impl.CouchbaseEntryManagerFactory; -import org.testng.annotations.Test; - -/** - * @author Yuriy Zabrovarnyy - */ -public class ManualCouchbaseEntryManagerTest { - - @Test(enabled = false) // manual - public void sample() throws IOException { - CouchbaseEntryManager manager = createCouchbaseEntryManager(); - - try { - List attributeList = manager.findEntries("o=gluu", SimpleClient.class, null); - System.out.println(attributeList); - } finally { - manager.destroy(); - } - } - - // MODIFY ACCORDING TO YOUR SERVER - public static Properties loadProperties() throws IOException { - Properties properties = new Properties(); - properties.put("couchbase.auth.userPassword", ""); - - try (InputStream is = ManualCouchbaseEntryManagerTest.class.getResourceAsStream("c1.gluu.org.properties")) { - properties.load(is); - return properties; - } - } - - public static CouchbaseEntryManager createCouchbaseEntryManager() throws IOException { - CouchbaseEntryManagerFactory couchbaseEntryManagerFactory = new CouchbaseEntryManagerFactory(); - couchbaseEntryManagerFactory.create(); - - CouchbaseEntryManager couchbaseEntryManager = couchbaseEntryManagerFactory.createEntryManager(loadProperties()); - System.out.println("Created CouchbaseEntryManager: " + couchbaseEntryManager); - - return couchbaseEntryManager; - } -} diff --git a/persistence-couchbase-sample/src/test/resources/org/gluu/couchbase/test/c1.gluu.org.properties b/persistence-couchbase-sample/src/test/resources/org/gluu/couchbase/test/c1.gluu.org.properties deleted file mode 100644 index ea38426c7..000000000 --- a/persistence-couchbase-sample/src/test/resources/org/gluu/couchbase/test/c1.gluu.org.properties +++ /dev/null @@ -1,6 +0,0 @@ -couchbase.servers=c1.gluu.org -couchbase.auth.userName=admin -couchbase.buckets=gluu -couchbase.bucket.default=gluu -couchbase.bucket.gluu.mapping=people, groups -couchbase.password.encryption.method=SSHA-256 \ No newline at end of file diff --git a/persistence-couchbase/LICENSE b/persistence-couchbase/LICENSE deleted file mode 100644 index cd069e7b4..000000000 --- a/persistence-couchbase/LICENSE +++ /dev/null @@ -1,25 +0,0 @@ -The Gluu Support License (GLUU-SUPPORT) - -Copyright (c) 2019 Gluu - -Permission is hereby granted to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The end-user person or organization using this software has an active support -subscription with either Gluu or one of Gluu's OEM partners after using the -software for more than 30 days. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/persistence-couchbase/pom.xml b/persistence-couchbase/pom.xml deleted file mode 100644 index cf13b511b..000000000 --- a/persistence-couchbase/pom.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - 4.0.0 - oxcore-persistence-couchbase - jar - persistence-couchbase - - - org.gluu - oxcore - 4.0.0-SNAPSHOT - - - - - - src/main/resources - true - - **/*.xml - **/services/* - **/*.properties - - - - - - - - - ${project.groupId} - oxcore-util - ${project.version} - - - ${project.groupId} - oxcore-persistence-filter - ${project.version} - - - ${project.groupId} - oxcore-persistence-core - ${project.version} - - - ${project.groupId} - oxcore-persistence-ldap - ${project.version} - - - org.gluu - oxcore-persistence-annotation - ${project.version} - - - - com.couchbase.client - java-client - - - - - javax.enterprise - cdi-api - provided - - - javax.inject - javax.inject - - - - - \ No newline at end of file diff --git a/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/impl/CouchbaseBatchOperationWraper.java b/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/impl/CouchbaseBatchOperationWraper.java deleted file mode 100644 index 5f1e6461b..000000000 --- a/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/impl/CouchbaseBatchOperationWraper.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - /* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2018, Gluu - */ - -package org.gluu.persist.couchbase.impl; - -import java.util.ArrayList; -import java.util.List; - -import org.gluu.persist.model.BatchOperation; -import org.gluu.persist.reflect.property.PropertyAnnotation; - -import com.couchbase.client.java.document.json.JsonObject; -import com.couchbase.client.java.query.N1qlQueryRow; - -/** - * Couchbase batch operation wrapper - * - * @author Yuriy Movchan Date: 05/16/2018 - */ -public class CouchbaseBatchOperationWraper { - - private CouchbaseEntryManager couchbaseEntryManager; - private Class entryClass; - private List propertiesAnnotations; - - private BatchOperation batchOperation; - - public CouchbaseBatchOperationWraper(BatchOperation batchOperation) { - this.batchOperation = batchOperation; - } - - public CouchbaseBatchOperationWraper(BatchOperation batchOperation, CouchbaseEntryManager couchbaseEntryManager, Class entryClass, - List propertiesAnnotations) { - this.batchOperation = batchOperation; - this.couchbaseEntryManager = couchbaseEntryManager; - this.entryClass = entryClass; - this.propertiesAnnotations = propertiesAnnotations; - } - - public final BatchOperation getBatchOperation() { - return batchOperation; - } - - public List createEntities(List searchResult) { - if (couchbaseEntryManager == null) { - return new ArrayList(0); - } - - JsonObject[] resultObjects = new JsonObject[searchResult.size()]; - - int index = 0; - for (N1qlQueryRow row : searchResult) { - resultObjects[index++] = row.value(); - } - - return couchbaseEntryManager.createEntities(entryClass, propertiesAnnotations, null, resultObjects); - } - -} diff --git a/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/impl/CouchbaseEntryManager.java b/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/impl/CouchbaseEntryManager.java deleted file mode 100644 index 6fa7f0c27..000000000 --- a/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/impl/CouchbaseEntryManager.java +++ /dev/null @@ -1,983 +0,0 @@ -/* - /* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2018, Gluu - */ - -package org.gluu.persist.couchbase.impl; - -import java.io.Serializable; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.function.Function; - -import javax.inject.Inject; - -import org.gluu.persist.annotation.AttributeName; -import org.gluu.persist.couchbase.model.ConvertedExpression; -import org.gluu.persist.couchbase.model.SearchReturnDataType; -import org.gluu.persist.couchbase.operation.CouchbaseOperationService; -import org.gluu.persist.couchbase.operation.impl.CouchbaseConnectionProvider; -import org.gluu.persist.couchbase.operation.impl.CouchbaseOperationsServiceImpl; -import org.gluu.persist.event.DeleteNotifier; -import org.gluu.persist.exception.AuthenticationException; -import org.gluu.persist.exception.EntryDeleteException; -import org.gluu.persist.exception.EntryPersistenceException; -import org.gluu.persist.exception.MappingException; -import org.gluu.persist.exception.operation.SearchException; -import org.gluu.persist.impl.BaseEntryManager; -import org.gluu.persist.key.impl.GenericKeyConverter; -import org.gluu.persist.key.impl.model.ParsedKey; -import org.gluu.persist.model.AttributeData; -import org.gluu.persist.model.AttributeDataModification; -import org.gluu.persist.model.AttributeDataModification.AttributeModificationType; -import org.gluu.persist.model.BatchOperation; -import org.gluu.persist.model.DefaultBatchOperation; -import org.gluu.persist.model.PagedResult; -import org.gluu.persist.model.SearchScope; -import org.gluu.persist.model.SortOrder; -import org.gluu.persist.reflect.property.PropertyAnnotation; -import org.gluu.persist.reflect.util.ReflectHelper; -import org.gluu.search.filter.Filter; -import org.gluu.util.ArrayHelper; -import org.gluu.util.StringHelper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.couchbase.client.core.message.kv.subdoc.multi.Mutation; -import com.couchbase.client.java.document.json.JsonArray; -import com.couchbase.client.java.document.json.JsonObject; -import com.couchbase.client.java.query.consistency.ScanConsistency; -import com.couchbase.client.java.query.dsl.Expression; -import com.couchbase.client.java.query.dsl.Sort; -import com.couchbase.client.java.subdoc.MutationSpec; - -/** - * Couchbase Entry Manager - * - * @author Yuriy Movchan Date: 05/14/2018 - */ -public class CouchbaseEntryManager extends BaseEntryManager implements Serializable { - - private static final long serialVersionUID = 2127241817126412574L; - - private static final Logger LOG = LoggerFactory.getLogger(CouchbaseConnectionProvider.class); - - @Inject - private Logger log; - - private final CouchbaseFilterConverter FILTER_CONVERTER; - private static final GenericKeyConverter KEY_CONVERTER = new GenericKeyConverter(); - - private SimpleDateFormat jsonDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"); - - private CouchbaseOperationsServiceImpl operationService; - private List subscribers; - - protected CouchbaseEntryManager(CouchbaseOperationsServiceImpl operationService) { - this.operationService = operationService; - this.FILTER_CONVERTER = new CouchbaseFilterConverter(this); - subscribers = new LinkedList(); - } - - @Override - public boolean destroy() { - if (this.operationService == null) { - return true; - } - - return this.operationService.destroy(); - } - - public CouchbaseOperationsServiceImpl getOperationService() { - return operationService; - } - - @Override - public void addDeleteSubscriber(DeleteNotifier subscriber) { - subscribers.add(subscriber); - } - - @Override - public void removeDeleteSubscriber(DeleteNotifier subscriber) { - subscribers.remove(subscriber); - } - - @Override - public T merge(T entry) { - Class entryClass = entry.getClass(); - checkEntryClass(entryClass, true); - if (isSchemaEntry(entryClass)) { - throw new UnsupportedOperationException("Server doesn't support dynamic schema modifications"); - } else { - return merge(entry, false, null); - } - } - - @Override - protected void updateMergeChanges(String baseDn, T entry, boolean isSchemaUpdate, Class entryClass, Map attributesFromDbMap, - List attributeDataModifications) { - // Update object classes if entry contains custom object classes - if (!isSchemaUpdate) { - String[] objectClasses = getObjectClasses(entry, entryClass); - if (ArrayHelper.isEmpty(objectClasses)) { - throw new UnsupportedOperationException(String.format("There is no attribute with objectClasses to persist! Entry is invalid: '%s'", entry)); - } - - AttributeData objectClassAttributeData = attributesFromDbMap.get(OBJECT_CLASS.toLowerCase()); - if (objectClassAttributeData == null) { - throw new UnsupportedOperationException(String.format("There is no attribute with objectClasses in DB! Entry is invalid: '%s'", entry)); - } - - String[] objectClassesFromDb = objectClassAttributeData.getStringValues(); - if (ArrayHelper.isEmpty(objectClassesFromDb)) { - throw new UnsupportedOperationException(String.format("There is no attribute with objectClasses in DB! Entry is invalid: '%s'", entry)); - } - - // We need to check only first element of each array because objectCLass in Couchbase is single value attribute - if (!StringHelper.equals(objectClassesFromDb[0], objectClasses[0])) { - attributeDataModifications.add(new AttributeDataModification(AttributeModificationType.REPLACE, - new AttributeData(OBJECT_CLASS, objectClasses, false), new AttributeData(OBJECT_CLASS, objectClassesFromDb, false))); - } - } - } - - @Override - public void remove(Object entry) { - Class entryClass = entry.getClass(); - checkEntryClass(entryClass, true); - if (isSchemaEntry(entryClass)) { - throw new UnsupportedOperationException("Server doesn't support dynamic schema modifications"); - } - - Object dnValue = getDNValue(entry, entryClass); - - LOG.debug("LDAP entry to remove: '{}'", dnValue.toString()); - - remove(dnValue.toString()); - } - - @Override - protected void persist(String dn, List attributes) { - JsonObject jsonObject = JsonObject.create(); - for (AttributeData attribute : attributes) { - String attributeName = attribute.getName(); - Object[] attributeValues = attribute.getValues(); - Boolean multiValued = attribute.getMultiValued(); - - - if (ArrayHelper.isNotEmpty(attributeValues) && (attributeValues[0] != null)) { - Object[] realValues = attributeValues; - - // We need to store only one objectClass value in Couchbase - if (StringHelper.equals(CouchbaseOperationService.OBJECT_CLASS, attributeName)) { - if (!ArrayHelper.isEmpty(realValues)) { - realValues = new Object[] { realValues[0] }; - multiValued = false; - } - } - - // Process userPassword - if (StringHelper.equals(CouchbaseOperationService.USER_PASSWORD, attributeName)) { - realValues = operationService.createStoragePassword(StringHelper.toStringArray(attributeValues)); - } - - escapeValues(realValues); - - if ((multiValued == null) || !multiValued) { - jsonObject.put(toInternalAttribute(attributeName), realValues[0]); - } else { - jsonObject.put(toInternalAttribute(attributeName), JsonArray.from(realValues)); - } - } - } - jsonObject.put(CouchbaseOperationService.DN, dn); - - // Persist entry - try { - boolean result = operationService.addEntry(toCouchbaseKey(dn).getKey(), jsonObject); - if (!result) { - throw new EntryPersistenceException(String.format("Failed to persist entry: %s", dn)); - } - } catch (Exception ex) { - throw new EntryPersistenceException(String.format("Failed to persist entry: %s", dn), ex); - } - } - - @Override - public void merge(String dn, List attributeDataModifications) { - // Update entry - try { - List modifications = new ArrayList(attributeDataModifications.size()); - for (AttributeDataModification attributeDataModification : attributeDataModifications) { - AttributeData attribute = attributeDataModification.getAttribute(); - AttributeData oldAttribute = attributeDataModification.getOldAttribute(); - - String attributeName = null; - Object[] attributeValues = null; - Boolean multiValued = null; - if (attribute != null) { - attributeName = attribute.getName(); - attributeValues = attribute.getValues(); - multiValued = attribute.getMultiValued(); - } - - String oldAttributeName = null; - Object[] oldAttributeValues = null; - if (oldAttribute != null) { - oldAttributeName = oldAttribute.getName(); - oldAttributeValues = oldAttribute.getValues(); - } - - MutationSpec modification = null; - if (AttributeModificationType.ADD.equals(attributeDataModification.getModificationType())) { - modification = createModification(Mutation.DICT_ADD, toInternalAttribute(attributeName), multiValued, attributeValues); - } else { - if (AttributeModificationType.REMOVE.equals(attributeDataModification.getModificationType())) { - modification = createModification(Mutation.DELETE, toInternalAttribute(oldAttributeName), multiValued, oldAttributeValues); - } else if (AttributeModificationType.REPLACE.equals(attributeDataModification.getModificationType())) { - modification = createModification(Mutation.REPLACE, toInternalAttribute(attributeName), multiValued, attributeValues); - } - } - - if (modification != null) { - modifications.add(modification); - } - } - - if (modifications.size() > 0) { - boolean result = operationService.updateEntry(toCouchbaseKey(dn).getKey(), modifications); - if (!result) { - throw new EntryPersistenceException(String.format("Failed to update entry: %s", dn)); - } - } - } catch (Exception ex) { - throw new EntryPersistenceException(String.format("Failed to update entry: %s", dn), ex); - } - } - - @Override - public void remove(String dn) { - // Remove entry - try { - for (DeleteNotifier subscriber : subscribers) { - subscriber.onBeforeRemove(dn); - } - operationService.delete(toCouchbaseKey(dn).getKey()); - for (DeleteNotifier subscriber : subscribers) { - subscriber.onAfterRemove(dn); - } - } catch (Exception ex) { - throw new EntryDeleteException(String.format("Failed to remove entry: %s", dn), ex); - } - } - - @Override - public void removeRecursively(String dn) { - try { - for (DeleteNotifier subscriber : subscribers) { - subscriber.onBeforeRemove(dn); - } - operationService.deleteRecursively(toCouchbaseKey(dn).getKey()); - for (DeleteNotifier subscriber : subscribers) { - subscriber.onAfterRemove(dn); - } - } catch (Exception ex) { - throw new EntryDeleteException(String.format("Failed to remove entry: %s", dn), ex); - } - } - - @Override - public int remove(String dn, Class entryClass, Filter filter, int count) { - if (StringHelper.isEmptyString(dn)) { - throw new MappingException("Base DN to delete entries is null"); - } - - // Remove entries by filter - return removeImpl(dn, entryClass, filter, count); - } - - protected int removeImpl(String dn, Class entryClass, Filter filter, int count) { - // Check entry class - checkEntryClass(entryClass, false); - - String[] objectClasses = getTypeObjectClasses(entryClass); - - Filter searchFilter; - if (objectClasses.length > 0) { - LOG.trace("Filter: {}", filter); - searchFilter = addObjectClassFilter(filter, objectClasses); - } else { - searchFilter = filter; - } - - // Find entries - LOG.trace("-------------------------------------------------------"); - LOG.trace("Filter: {}", filter); - LOG.trace("objectClasses count: {} ", objectClasses.length); - LOG.trace("objectClasses: {}", objectClasses.toString()); - LOG.trace("Search filter: {}", searchFilter); - - // Prepare properties types to allow build filter properly - List propertiesAnnotations = getEntryPropertyAnnotations(entryClass); - Map propertiesAnnotationsMap = prepareEntryPropertiesTypes(entryClass, propertiesAnnotations); - - ParsedKey keyWithInum = toCouchbaseKey(dn); - ConvertedExpression convertedExpression; - try { - convertedExpression = toCouchbaseFilter(searchFilter, propertiesAnnotationsMap); - } catch (SearchException ex) { - throw new EntryDeleteException(String.format("Failed to convert filter %s to expression", searchFilter)); - } - - try { - int processed = operationService.delete(keyWithInum.getKey(), getScanConsistency(convertedExpression), convertedExpression.expression(), count); - - return processed; - } catch (Exception ex) { - throw new EntryDeleteException(String.format("Failed to delete entries with key: %s, expression: %s", keyWithInum.getKey(), convertedExpression), ex); - } - } - - @Override - protected List find(String dn, Map propertiesAnnotationsMap, String... ldapReturnAttributes) { - try { - // Load entry - ParsedKey keyWithInum = toCouchbaseKey(dn); - ScanConsistency scanConsistency = getScanConsistency(keyWithInum.getName(), propertiesAnnotationsMap); - JsonObject entry = operationService.lookup(keyWithInum.getKey(), scanConsistency, toInternalAttributes(ldapReturnAttributes)); - List result = getAttributeDataList(entry); - if (result != null) { - return result; - } - } catch (Exception ex) { - throw new EntryPersistenceException(String.format("Failed to find entry: %s", dn), ex); - } - - throw new EntryPersistenceException(String.format("Failed to find entry: %s", dn)); - } - - @Override - public List findEntries(String baseDN, Class entryClass, Filter filter, SearchScope scope, String[] ldapReturnAttributes, - BatchOperation batchOperation, int start, int count, int chunkSize) { - if (StringHelper.isEmptyString(baseDN)) { - throw new MappingException("Base DN to find entries is null"); - } - - PagedResult searchResult = findEntriesImpl(baseDN, entryClass, filter, scope, ldapReturnAttributes, null, null, batchOperation, - SearchReturnDataType.SEARCH, start, count, chunkSize); - if (searchResult.getEntriesCount() == 0) { - return new ArrayList(0); - } - - List entries = createEntities(baseDN, entryClass, searchResult); - - return entries; - } - - @Override - public PagedResult findPagedEntries(String baseDN, Class entryClass, Filter filter, String[] ldapReturnAttributes, String sortBy, - SortOrder sortOrder, int start, int count, int chunkSize) { - if (StringHelper.isEmptyString(baseDN)) { - throw new MappingException("Base DN to find entries is null"); - } - - PagedResult searchResult = findEntriesImpl(baseDN, entryClass, filter, SearchScope.SUB, ldapReturnAttributes, sortBy, sortOrder, - null, SearchReturnDataType.SEARCH_COUNT, start, count, chunkSize); - - PagedResult result = new PagedResult(); - result.setEntriesCount(searchResult.getEntriesCount()); - result.setStart(searchResult.getStart()); - result.setTotalEntriesCount(searchResult.getTotalEntriesCount()); - - if (searchResult.getEntriesCount() == 0) { - result.setEntries(new ArrayList(0)); - return result; - } - - List entries = createEntities(baseDN, entryClass, searchResult); - result.setEntries(entries); - - return result; - } - - protected PagedResult findEntriesImpl(String baseDN, Class entryClass, Filter filter, SearchScope scope, - String[] ldapReturnAttributes, String sortBy, SortOrder sortOrder, BatchOperation batchOperation, SearchReturnDataType returnDataType, int start, - int count, int chunkSize) { - // Check entry class - checkEntryClass(entryClass, false); - String[] objectClasses = getTypeObjectClasses(entryClass); - - List propertiesAnnotations = getEntryPropertyAnnotations(entryClass); - String[] currentLdapReturnAttributes = ldapReturnAttributes; - if (ArrayHelper.isEmpty(currentLdapReturnAttributes)) { - currentLdapReturnAttributes = getAttributes(null, propertiesAnnotations, false); - } - - Filter searchFilter; - if (objectClasses.length > 0) { - LOG.trace("Filter: {}", filter); - searchFilter = addObjectClassFilter(filter, objectClasses); - } else { - searchFilter = filter; - } - - // Find entries - LOG.trace("-------------------------------------------------------"); - LOG.trace("Filter: {}", filter); - LOG.trace("objectClasses count: {} ", objectClasses.length); - LOG.trace("objectClasses: {}", ArrayHelper.toString(objectClasses)); - LOG.trace("Search filter: {}", searchFilter); - - // Prepare default sort - Sort[] defaultSort = getDefaultSort(entryClass); - - if (StringHelper.isNotEmpty(sortBy)) { - Sort requestedSort = buildSort(sortBy, sortOrder); - - if (ArrayHelper.isEmpty(defaultSort)) { - defaultSort = new Sort[] { requestedSort }; - } else { - defaultSort = ArrayHelper.arrayMerge(new Sort[] { requestedSort }, defaultSort); - } - } - - // Prepare properties types to allow build filter properly - Map propertiesAnnotationsMap = prepareEntryPropertiesTypes(entryClass, propertiesAnnotations); - ParsedKey keyWithInum = toCouchbaseKey(baseDN); - ConvertedExpression convertedExpression; - try { - convertedExpression = toCouchbaseFilter(searchFilter, propertiesAnnotationsMap); - } catch (SearchException ex) { - throw new EntryPersistenceException(String.format("Failed to convert filter %s to expression", searchFilter)); - } - - PagedResult searchResult = null; - try { - CouchbaseBatchOperationWraper batchOperationWraper = null; - if (batchOperation != null) { - batchOperationWraper = new CouchbaseBatchOperationWraper(batchOperation, this, entryClass, propertiesAnnotations); - } - searchResult = searchImpl(keyWithInum.getKey(), getScanConsistency(convertedExpression), convertedExpression.expression(), scope, currentLdapReturnAttributes, - defaultSort, batchOperationWraper, returnDataType, start, count, chunkSize); - - if (searchResult == null) { - throw new EntryPersistenceException(String.format("Failed to find entries with key: %s, expression: %s", keyWithInum.getKey(), convertedExpression)); - } - - return searchResult; - } catch (Exception ex) { - throw new EntryPersistenceException(String.format("Failed to find entries with key: %s, expression: %s", keyWithInum.getKey(), convertedExpression), ex); - } - } - - @Override - protected boolean contains(String baseDN, Class entryClass, List propertiesAnnotations, Filter filter, String[] objectClasses, String[] ldapReturnAttributes) { - if (StringHelper.isEmptyString(baseDN)) { - throw new MappingException("Base DN to check contain entries is null"); - } - - // Create filter - Filter searchFilter; - if (objectClasses.length > 0) { - searchFilter = addObjectClassFilter(filter, objectClasses); - } else { - searchFilter = filter; - } - - // Prepare properties types to allow build filter properly - Map propertiesAnnotationsMap = prepareEntryPropertiesTypes(entryClass, propertiesAnnotations); - - ConvertedExpression convertedExpression; - try { - convertedExpression = toCouchbaseFilter(searchFilter, propertiesAnnotationsMap); - } catch (SearchException ex) { - throw new EntryPersistenceException(String.format("Failed to convert filter %s to expression", searchFilter)); - } - - PagedResult searchResult = null; - try { - ParsedKey keyWithInum = toCouchbaseKey(baseDN); - searchResult = searchImpl(keyWithInum.getKey(), getScanConsistency(convertedExpression), convertedExpression.expression(), SearchScope.SUB, ldapReturnAttributes, null, - null, SearchReturnDataType.SEARCH, 1, 1, 0); - if (searchResult == null) { - throw new EntryPersistenceException(String.format("Failed to find entry with baseDN: %s, filter: %s", baseDN, searchFilter)); - } - } catch (Exception ex) { - throw new EntryPersistenceException(String.format("Failed to find entry with baseDN: %s, filter: %s", baseDN, searchFilter), ex); - } - - return (searchResult != null) && (searchResult.getEntriesCount() > 0); - } - - private PagedResult searchImpl(String key, ScanConsistency scanConsistency, Expression expression, SearchScope scope, String[] attributes, Sort[] orderBy, - CouchbaseBatchOperationWraper batchOperationWraper, SearchReturnDataType returnDataType, int start, int count, int pageSize) throws SearchException { - return operationService.search(key, scanConsistency, expression, scope, toInternalAttributes(attributes), orderBy, batchOperationWraper, returnDataType, start, count, pageSize); - } - - protected List createEntities(String baseDN, Class entryClass, PagedResult searchResult) { - ParsedKey keyWithInum = toCouchbaseKey(baseDN); - List propertiesAnnotations = getEntryPropertyAnnotations(entryClass); - List entries = createEntities(entryClass, propertiesAnnotations, keyWithInum, - searchResult.getEntries().toArray(new JsonObject[searchResult.getEntriesCount()])); - - return entries; - } - - protected List createEntities(Class entryClass, List propertiesAnnotations, ParsedKey baseDn, - JsonObject... searchResultEntries) { - List result = new ArrayList(searchResultEntries.length); - Map> entriesAttributes = new LinkedHashMap>(100); - - int count = 0; - for (int i = 0; i < searchResultEntries.length; i++) { - count++; - JsonObject entry = searchResultEntries[i]; - // String key = entry.getString(CouchbaseOperationService.META_DOC_ID); - String dn = entry.getString(fromInternalAttribute(CouchbaseOperationService.DN)); - entriesAttributes.put(dn, getAttributeDataList(entry)); - - // Remove reference to allow java clean up object - searchResultEntries[i] = null; - - // Allow java to clean up temporary objects - if (count >= 100) { - List currentResult = createEntities(entryClass, propertiesAnnotations, entriesAttributes); - result.addAll(currentResult); - - entriesAttributes = new LinkedHashMap>(100); - count = 0; - } - } - - List currentResult = createEntities(entryClass, propertiesAnnotations, entriesAttributes); - result.addAll(currentResult); - - return result; - } - - private List getAttributeDataList(JsonObject entry) { - if (entry == null) { - return null; - } - - List result = new ArrayList(); - for (String shortAttributeName : entry.getNames()) { - Object attributeObject = entry.get(shortAttributeName); - - String attributeName = fromInternalAttribute(shortAttributeName); - - Boolean multiValued = Boolean.FALSE; - Object[] attributeValueObjects; - if (attributeObject == null) { - attributeValueObjects = NO_OBJECTS; - } - if (attributeObject instanceof JsonArray) { - JsonArray jsonArray = (JsonArray) attributeObject; - ArrayList resultList = new ArrayList(jsonArray.size()); - for (Iterator it = jsonArray.iterator(); it.hasNext();) { - resultList.add(it.next()); - } - attributeValueObjects = resultList.toArray(NO_OBJECTS); - multiValued = Boolean.TRUE; - } else { - if ((attributeObject instanceof Boolean) || (attributeObject instanceof Integer) || (attributeObject instanceof Long) || - (attributeObject instanceof JsonObject)) { - attributeValueObjects = new Object[] { attributeObject }; - } else if (attributeObject instanceof String) { - Object value = attributeObject.toString(); - try { - value = jsonDateFormat.parse(attributeObject.toString()); - } catch (Exception ex) {} - attributeValueObjects = new Object[] { value }; - } else { - Object value = attributeObject.toString(); - attributeValueObjects = new Object[] { value }; - } - } - - unescapeValues(attributeValueObjects); - - AttributeData tmpAttribute = new AttributeData(attributeName, attributeValueObjects); - if (multiValued != null) { - tmpAttribute.setMultiValued(multiValued); - } - result.add(tmpAttribute); - } - - return result; - } - - @Override - public boolean authenticate(String baseDN, String userName, String password) { - Filter searchFilter = Filter.createEqualityFilter(CouchbaseOperationService.UID, userName); - - ConvertedExpression convertedExpression; - try { - convertedExpression = toCouchbaseFilter(searchFilter, null); - } catch (SearchException ex) { - throw new EntryPersistenceException(String.format("Failed to convert filter %s to expression", searchFilter)); - } - - try { - PagedResult searchResult = searchImpl(toCouchbaseKey(baseDN).getKey(), getScanConsistency(convertedExpression), convertedExpression.expression(), - SearchScope.SUB, null, null, null, SearchReturnDataType.SEARCH, 0, 1, 1); - if ((searchResult == null) || (searchResult.getEntriesCount() != 1)) { - return false; - } - - String bindDn = searchResult.getEntries().get(0).getString(CouchbaseOperationService.DN); - - return authenticate(bindDn, password); - } catch (SearchException ex) { - throw new AuthenticationException(String.format("Failed to find user DN: %s", userName), ex); - } catch (Exception ex) { - throw new AuthenticationException(String.format("Failed to authenticate user: %s", userName), ex); - } - } - - @Override - public boolean authenticate(String bindDn, String password) { - try { - return operationService.authenticate(toCouchbaseKey(bindDn).getKey(), escapeValue(password)); - } catch (Exception ex) { - throw new AuthenticationException(String.format("Failed to authenticate DN: %s", bindDn), ex); - } - } - - @Override - public int countEntries(String baseDN, Class entryClass, Filter filter) { - return countEntries(baseDN, entryClass, filter, SearchScope.SUB); - } - - @Override - public int countEntries(String baseDN, Class entryClass, Filter filter, SearchScope scope) { - if (StringHelper.isEmptyString(baseDN)) { - throw new MappingException("Base DN to find entries is null"); - } - - // Check entry class - checkEntryClass(entryClass, false); - String[] objectClasses = getTypeObjectClasses(entryClass); - List propertiesAnnotations = getEntryPropertyAnnotations(entryClass); - - // Find entries - Filter searchFilter; - if (objectClasses.length > 0) { - searchFilter = addObjectClassFilter(filter, objectClasses); - } else { - searchFilter = filter; - } - - // Prepare properties types to allow build filter properly - Map propertiesAnnotationsMap = prepareEntryPropertiesTypes(entryClass, propertiesAnnotations); - - ConvertedExpression convertedExpression; - try { - convertedExpression = toCouchbaseFilter(searchFilter, propertiesAnnotationsMap); - } catch (SearchException ex) { - throw new EntryPersistenceException(String.format("Failed to convert filter %s to expression", searchFilter)); - } - - PagedResult searchResult; - try { - searchResult = searchImpl(toCouchbaseKey(baseDN).getKey(), getScanConsistency(convertedExpression), convertedExpression.expression(), scope, null, null, - null, SearchReturnDataType.COUNT, 0, 0, 0); - } catch (Exception ex) { - throw new EntryPersistenceException( - String.format("Failed to calculate the number of entries with baseDN: %s, filter: %s", baseDN, searchFilter), ex); - } - - return searchResult.getTotalEntriesCount(); - } - - private MutationSpec createModification(final Mutation type, final String attributeName, final Boolean multiValued, final Object... attributeValues) { - String realAttributeName = attributeName; - - Object[] realValues = attributeValues; - if (StringHelper.equals(CouchbaseOperationService.USER_PASSWORD, realAttributeName)) { - realValues = operationService.createStoragePassword(StringHelper.toStringArray(attributeValues)); - } - - escapeValues(realValues); - - if ((multiValued == null) || !multiValued) { - return new MutationSpec(type, realAttributeName, realValues[0]); - } else { - return new MutationSpec(type, realAttributeName, realValues); - } - } - - protected Sort buildSort(String sortBy, SortOrder sortOrder) { - Sort requestedSort = null; - if (SortOrder.DESCENDING == sortOrder) { - requestedSort = Sort.desc(Expression.path(sortBy)); - } else if (SortOrder.ASCENDING == sortOrder) { - requestedSort = Sort.asc(Expression.path(sortBy)); - } else { - requestedSort = Sort.def(Expression.path(sortBy)); - } - return requestedSort; - } - - protected Sort[] getDefaultSort(Class entryClass) { - String[] sortByProperties = getEntrySortBy(entryClass); - - if (ArrayHelper.isEmpty(sortByProperties)) { - return null; - } - - Sort[] sort = new Sort[sortByProperties.length]; - for (int i = 0; i < sortByProperties.length; i++) { - sort[i] = Sort.def(Expression.path(sortByProperties[i])); - } - - return sort; - } - - @Override - public List exportEntry(String dn) { - try { - // Load entry - ParsedKey keyWithInum = toCouchbaseKey(dn); - JsonObject entry = operationService.lookup(keyWithInum.getKey(), null); - - List result = getAttributeDataList(entry); - if (result != null) { - return result; - } - - return null; - } catch (Exception ex) { - throw new EntryPersistenceException(String.format("Failed to find entry: %s", dn), ex); - } - } - @Override - public void importEntry(String dn, List attributes) { - persist(dn, attributes); - } - - private ConvertedExpression toCouchbaseFilter(Filter genericFilter, Map propertiesAnnotationsMap) throws SearchException { - return FILTER_CONVERTER.convertToCouchbaseFilter(genericFilter, propertiesAnnotationsMap); - } - - private ConvertedExpression toCouchbaseFilter(Filter genericFilter, Map propertiesAnnotationsMap, Function processor) throws SearchException { - return FILTER_CONVERTER.convertToCouchbaseFilter(genericFilter, propertiesAnnotationsMap, processor); - } - - private ParsedKey toCouchbaseKey(String dn) { - return KEY_CONVERTER.convertToKey(dn); - } - - @Override - protected Filter addObjectClassFilter(Filter filter, String[] objectClasses) { - if (objectClasses.length == 0) { - return filter; - } - - // In Couchbase implementation we need to use first one as entry type - Filter searchFilter = Filter.createEqualityFilter(OBJECT_CLASS, objectClasses[0]); - if (filter != null) { - searchFilter = Filter.createANDFilter(Filter.createANDFilter(searchFilter), filter); - } - - return searchFilter; - } - - private static final class CountBatchOperation extends DefaultBatchOperation { - - private int countEntries = 0; - - @Override - public void performAction(List entries) { - } - - @Override - public boolean collectSearchResult(int size) { - countEntries += size; - return false; - } - - public int getCountEntries() { - return countEntries; - } - } - - @Override - public String encodeTime(String baseDN, Date date) { - if (date == null) { - return null; - } - - return jsonDateFormat.format(date); - } - - @Override - protected String encodeTime(Date date) { - return encodeTime(null, date); - } - - @Override - public Date decodeTime(String baseDN, String date) { - if (StringHelper.isEmpty(date)) { - return null; - } - - Date decodedDate; - try { - decodedDate = jsonDateFormat.parse(date); - } catch (ParseException ex) { - LOG.error("Failed to decode generalized time '{}'", date, ex); - - return null; - } - - return decodedDate; - } - - @Override - public Date decodeTime(String date) { - return decodeTime(null, date); - } - - @Override - public boolean hasBranchesSupport(String dn) { - return false; - } - - @Override - public String getPersistenceType(String primaryKey) { - return CouchbaseEntryManagerFactory.PERSISTANCE_TYPE; - } - - @Override - protected Object convertValueToJson(Object propertyValue) { - String jsonStringPropertyValue = (String) super.convertValueToJson(propertyValue); - return JsonObject.fromJson(jsonStringPropertyValue); - } - - @Override - protected Object convertJsonToValue(Class parameterType, Object propertyValue) { - Object jsonStringPropertyValue = propertyValue; - if (propertyValue instanceof JsonObject) { - JsonObject jsonObject = (JsonObject) propertyValue; - jsonStringPropertyValue = jsonObject.toString(); - } - - return super.convertJsonToValue(parameterType, jsonStringPropertyValue); - } - - private ScanConsistency getScanConsistency(ConvertedExpression convertedExpression) { - if (convertedExpression.consistency()) { - return ScanConsistency.REQUEST_PLUS; - } - - return null; - } - - private ScanConsistency getScanConsistency(String attributeName, Map propertiesAnnotationsMap) { - if (StringHelper.isEmpty(attributeName)) { - return null; - } - - PropertyAnnotation propertyAnnotation = propertiesAnnotationsMap.get(attributeName); - if ((propertyAnnotation == null) || (propertyAnnotation.getParameterType() == null)) { - return null; - } - AttributeName attributeNameAnnotation = (AttributeName) ReflectHelper.getAnnotationByType(propertyAnnotation.getAnnotations(), - AttributeName.class); - - if (attributeNameAnnotation.consistency()) { - return ScanConsistency.REQUEST_PLUS; - } - - return null; - } - - private String escapeValue(String value) { - // Couchbade SDK do this automatically -// return StringHelper.escapeJson(value); - return value; - } - - private String unescapeValue(String value) { - // Couchbade SDK do this automatically -// return StringHelper.unescapeJson(value); - return value; - } - - private void escapeValues(Object[] realValues) { - // Couchbade SDK do this automatically -// for (int i = 0; i < realValues.length; i++) { -// if (realValues[i] instanceof String) { -// realValues[i] = StringHelper.escapeJson(realValues[i]); -// } -// } - } - - private void unescapeValues(Object[] realValues) { - // Couchbade SDK do this automatically -// for (int i = 0; i < realValues.length; i++) { -// if (realValues[i] instanceof String) { -// realValues[i] = StringHelper.unescapeJson(realValues[i]); -// } -// } - } - - public String toInternalAttribute(String attributeName) { - return attributeName; -// if (operationService.isDisableAttributeMapping()) { -// return attributeName; -// } -// -// return KeyShortcuter.shortcut(attributeName); - } - - public String[] toInternalAttributes(String[] attributeNames) { - return attributeNames; -// if (operationService.isDisableAttributeMapping() || ArrayHelper.isEmpty(attributeNames)) { -// return attributeNames; -// } -// -// String[] resultAttributeNames = new String[attributeNames.length]; -// -// for (int i = 0; i < attributeNames.length; i++) { -// resultAttributeNames[i] = KeyShortcuter.shortcut(attributeNames[i]); -// } -// -// return resultAttributeNames; - } - - public String fromInternalAttribute(String internalAttributeName) { - return internalAttributeName; -// if (operationService.isDisableAttributeMapping()) { -// return internalAttributeName; -// } -// -// return KeyShortcuter.fromShortcut(internalAttributeName); - } - - public String[] fromInternalAttributes(String[] internalAttributeNames) { - return internalAttributeNames; -// if (operationService.isDisableAttributeMapping() || ArrayHelper.isEmpty(internalAttributeNames)) { -// return internalAttributeNames; -// } -// -// String[] resultAttributeNames = new String[internalAttributeNames.length]; -// -// for (int i = 0; i < internalAttributeNames.length; i++) { -// resultAttributeNames[i] = KeyShortcuter.fromShortcut(internalAttributeNames[i]); -// } -// -// return resultAttributeNames; - } - -} diff --git a/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/impl/CouchbaseEntryManagerFactory.java b/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/impl/CouchbaseEntryManagerFactory.java deleted file mode 100644 index fd53a0dbc..000000000 --- a/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/impl/CouchbaseEntryManagerFactory.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - /* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2018, Gluu - */ - -package org.gluu.persist.couchbase.impl; - -import java.util.HashMap; -import java.util.Properties; - -import javax.annotation.PostConstruct; -import javax.enterprise.context.ApplicationScoped; - -import org.gluu.persist.PersistenceEntryManagerFactory; -import org.gluu.persist.couchbase.operation.impl.CouchbaseConnectionProvider; -import org.gluu.persist.couchbase.operation.impl.CouchbaseOperationsServiceImpl; -import org.gluu.persist.exception.operation.ConfigurationException; -import org.gluu.persist.service.BaseFactoryService; -import org.gluu.util.PropertiesHelper; -import org.gluu.util.StringHelper; -import org.gluu.util.init.Initializable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.couchbase.client.java.env.CouchbaseEnvironment; -import com.couchbase.client.java.env.DefaultCouchbaseEnvironment; - -/** - * Couchbase Entry Manager Factory - * - * @author Yuriy Movchan Date: 05/31/2018 - */ -@ApplicationScoped -public class CouchbaseEntryManagerFactory extends Initializable implements PersistenceEntryManagerFactory { - - private static final Logger LOG = LoggerFactory.getLogger(CouchbaseEntryManagerFactory.class); - - public static final String PERSISTANCE_TYPE = "couchbase"; - - private DefaultCouchbaseEnvironment.Builder builder; - private CouchbaseEnvironment couchbaseEnvironment; - - private Properties couchbaseConnectionProperties; - - @PostConstruct - public void create() { - this.builder = DefaultCouchbaseEnvironment.builder().operationTracingEnabled(false); - } - - @Override - protected void initInternal() { - // SSL settings - boolean useSSL = Boolean.valueOf(couchbaseConnectionProperties.getProperty("ssl.trustStore.enable")).booleanValue(); - if (useSSL) { - String sslTrustStoreFile = couchbaseConnectionProperties.getProperty("ssl.trustStore.file"); - String sslTrustStorePin = couchbaseConnectionProperties.getProperty("ssl.trustStore.pin"); - - builder.sslEnabled(true).sslTruststoreFile(sslTrustStoreFile).sslTruststorePassword(sslTrustStorePin); - } else { - builder.sslEnabled(false); - } - - String connectTimeoutString = couchbaseConnectionProperties.getProperty("connection.connect-timeout"); - if (StringHelper.isNotEmpty(connectTimeoutString)) { - int connectTimeout = Integer.valueOf(connectTimeoutString); - builder.connectTimeout(connectTimeout); - } - - String operationTracingEnabledString = couchbaseConnectionProperties.getProperty("connection.operation-tracing-enabled"); - if (StringHelper.isNotEmpty(operationTracingEnabledString)) { - boolean operationTracingEnabled = Boolean.valueOf(operationTracingEnabledString); - builder.operationTracingEnabled(operationTracingEnabled); - } - - String mutationTokensEnabledString = couchbaseConnectionProperties.getProperty("connection.mutation-tokens-enabled"); - if (StringHelper.isNotEmpty(mutationTokensEnabledString)) { - boolean mutationTokensEnabled = Boolean.valueOf(mutationTokensEnabledString); - builder.mutationTokensEnabled(mutationTokensEnabled); - } - - String computationPoolSizeString = couchbaseConnectionProperties.getProperty("connection.computation-pool-size"); - if (StringHelper.isNotEmpty(computationPoolSizeString)) { - int computationPoolSize = Integer.valueOf(computationPoolSizeString); - builder.computationPoolSize(computationPoolSize); - } - - this.couchbaseEnvironment = builder.build(); - - this.builder = null; - } - - @Override - public String getPersistenceType() { - return PERSISTANCE_TYPE; - } - - @Override - public HashMap getConfigurationFileNames() { - HashMap confs = new HashMap(); - confs.put(PERSISTANCE_TYPE, "gluu-couchbase.properties"); - - return confs; - } - - public CouchbaseEnvironment getCouchbaseEnvironment() { - return couchbaseEnvironment; - } - - @Override - public CouchbaseEntryManager createEntryManager(Properties conf) { - Properties entryManagerConf = PropertiesHelper.filterProperties(conf, PERSISTANCE_TYPE); - - // Allow proper initialization - if (this.couchbaseConnectionProperties == null) { - this.couchbaseConnectionProperties = entryManagerConf; - } - - init(); - - if (!isInitialized()) { - throw new ConfigurationException("Failed to create Couchbase environment!"); - } - - CouchbaseConnectionProvider connectionProvider = new CouchbaseConnectionProvider(entryManagerConf, couchbaseEnvironment); - connectionProvider.create(); - if (!connectionProvider.isCreated()) { - throw new ConfigurationException( - String.format("Failed to create Couchbase connection pool! Result code: '%s'", connectionProvider.getCreationResultCode())); - } - LOG.debug("Created connectionProvider '{}' with code '{}'", connectionProvider, connectionProvider.getCreationResultCode()); - - CouchbaseEntryManager couchbaseEntryManager = new CouchbaseEntryManager(new CouchbaseOperationsServiceImpl(entryManagerConf, connectionProvider)); - LOG.info("Created CouchbaseEntryManager: {}", couchbaseEntryManager.getOperationService()); - - return couchbaseEntryManager; - } - - @Override - public void initStandalone(BaseFactoryService persistanceFactoryService) { - this.builder = DefaultCouchbaseEnvironment.builder().mutationTokensEnabled(true).computationPoolSize(5); - } - - -/* - public static void main(String[] args) throws FileNotFoundException, IOException { - Properties prop = new Properties(); - prop.load(new FileInputStream(new File("D:/Temp/gluu-couchbase.properties"))); - - CouchbaseEntryManagerFactory cemf = new CouchbaseEntryManagerFactory(); - cemf.create(); - - CouchbaseEntryManager cem = cemf.createEntryManager(prop); - - System.out.println(cem.getOperationService().getConnectionProvider().isCreated()); - - } -*/ -} diff --git a/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/impl/CouchbaseFilterConverter.java b/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/impl/CouchbaseFilterConverter.java deleted file mode 100644 index 560c9a768..000000000 --- a/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/impl/CouchbaseFilterConverter.java +++ /dev/null @@ -1,289 +0,0 @@ -/* - /* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2018, Gluu - */ - -package org.gluu.persist.couchbase.impl; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.function.Function; - -import javax.enterprise.context.ApplicationScoped; - -import org.gluu.persist.annotation.AttributeEnum; -import org.gluu.persist.annotation.AttributeName; -import org.gluu.persist.couchbase.model.ConvertedExpression; -import org.gluu.persist.exception.operation.SearchException; -import org.gluu.persist.ldap.impl.LdapFilterConverter; -import org.gluu.persist.reflect.property.PropertyAnnotation; -import org.gluu.persist.reflect.util.ReflectHelper; -import org.gluu.search.filter.Filter; -import org.gluu.search.filter.FilterType; -import org.gluu.util.ArrayHelper; -import org.gluu.util.StringHelper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.couchbase.client.java.document.json.JsonArray; -import com.couchbase.client.java.query.dsl.Expression; -import com.couchbase.client.java.query.dsl.functions.StringFunctions; - -/** - * Filter to Couchbase expressions convert - * - * @author Yuriy Movchan Date: 05/15/2018 - */ -@ApplicationScoped -public class CouchbaseFilterConverter { - - private static final Logger LOG = LoggerFactory.getLogger(CouchbaseFilterConverter.class); - - private LdapFilterConverter ldapFilterConverter = new LdapFilterConverter(); - - private CouchbaseEntryManager couchbaseEntryManager; - - public CouchbaseFilterConverter(CouchbaseEntryManager couchbaseEntryManager) { - this.couchbaseEntryManager = couchbaseEntryManager; - } - - public ConvertedExpression convertToCouchbaseFilter(Filter genericFilter, Map propertiesAnnotationsMap) throws SearchException { - return convertToCouchbaseFilter(genericFilter, propertiesAnnotationsMap, null); - } - - public ConvertedExpression convertToCouchbaseFilter(Filter genericFilter, Map propertiesAnnotationsMap, Function processor) throws SearchException { - Filter currentGenericFilter = genericFilter; - - FilterType type = currentGenericFilter.getType(); - if (FilterType.RAW == type) { - LOG.warn("RAW Ldap filter to Couchbase convertion will be removed in new version!!!"); - currentGenericFilter = ldapFilterConverter.convertRawLdapFilterToFilter(currentGenericFilter.getFilterString()); - type = currentGenericFilter.getType(); - } - - boolean requiredConsistency = isRequiredConsistency(currentGenericFilter, propertiesAnnotationsMap); - - if (processor != null) { - processor.apply(currentGenericFilter); - } - - if ((FilterType.NOT == type) || (FilterType.AND == type) || (FilterType.OR == type)) { - Filter[] genericFilters = currentGenericFilter.getFilters(); - ConvertedExpression[] expFilters = new ConvertedExpression[genericFilters.length]; - - if (genericFilters != null) { - boolean canJoinOrFilters = FilterType.OR == type; // We can replace only multiple OR with IN - List joinOrFilters = new ArrayList(); - String joinOrAttributeName = null; - for (int i = 0; i < genericFilters.length; i++) { - Filter tmpFilter = genericFilters[i]; - expFilters[i] = convertToCouchbaseFilter(tmpFilter, propertiesAnnotationsMap, processor); - - // Check if we can replace OR with IN - if (!canJoinOrFilters) { - continue; - } - - if ((FilterType.EQUALITY != tmpFilter.getType()) || (tmpFilter.getFilters() != null)) { - canJoinOrFilters = false; - continue; - } - - Boolean isMultiValuedDetected = determineMultiValuedByType(tmpFilter.getAttributeName(), propertiesAnnotationsMap); - if (!Boolean.FALSE.equals(isMultiValuedDetected)) { - canJoinOrFilters = false; - continue; - } - - if (joinOrAttributeName == null) { - joinOrAttributeName = tmpFilter.getAttributeName(); - joinOrFilters.add(tmpFilter); - continue; - } - if (!joinOrAttributeName.equals(tmpFilter.getAttributeName())) { - canJoinOrFilters = false; - continue; - } - joinOrFilters.add(tmpFilter); - } - - if (FilterType.NOT == type) { - return ConvertedExpression.build(Expression.par(expFilters[0].expression().not()), expFilters[0].consistency()); - } else if (FilterType.AND == type) { - for (int i = 0; i < expFilters.length; i++) { - requiredConsistency |= expFilters[i].consistency(); - } - - Expression result = expFilters[0].expression(); - for (int i = 1; i < expFilters.length; i++) { - result = result.and(expFilters[i].expression()); - } - return ConvertedExpression.build(Expression.par(result), requiredConsistency); - } else if (FilterType.OR == type) { - for (int i = 0; i < expFilters.length; i++) { - requiredConsistency |= expFilters[i].consistency(); - } - - if (canJoinOrFilters) { - JsonArray jsonArrayValues = JsonArray.create(); - for (Filter eqFilter : joinOrFilters) { - jsonArrayValues.add(eqFilter.getAssertionValue()); - } - Expression exp = Expression - .par(Expression.path(Expression.path(joinOrAttributeName)).in(jsonArrayValues)); - return ConvertedExpression.build(exp, requiredConsistency); - } else { - Expression result = expFilters[0].expression(); - for (int i = 1; i < expFilters.length; i++) { - result = result.or(expFilters[i].expression()); - } - - return ConvertedExpression.build(Expression.par(result), requiredConsistency); - } - } - } - } - - if (FilterType.EQUALITY == type) { - boolean hasSubFilters = ArrayHelper.isNotEmpty(currentGenericFilter.getFilters()); - Boolean isMultiValuedDetected = determineMultiValuedByType(currentGenericFilter.getAttributeName(), propertiesAnnotationsMap); - if (Boolean.TRUE.equals(currentGenericFilter.getMultiValued()) || Boolean.TRUE.equals(isMultiValuedDetected)) { - return ConvertedExpression.build(Expression.path(buildTypedExpression(currentGenericFilter).in(Expression.path(toInternalAttribute(currentGenericFilter)))), requiredConsistency); - } else if (Boolean.FALSE.equals(currentGenericFilter.getMultiValued()) || Boolean.FALSE.equals(isMultiValuedDetected)) { - if (hasSubFilters) { - ConvertedExpression nameConvertedExpression = convertToCouchbaseFilter(currentGenericFilter.getFilters()[0], propertiesAnnotationsMap); - return ConvertedExpression.build(nameConvertedExpression.expression().eq(buildTypedExpression(currentGenericFilter)), requiredConsistency); - } - return ConvertedExpression.build(Expression.path(Expression.path(toInternalAttribute(currentGenericFilter))).eq(buildTypedExpression(currentGenericFilter)), requiredConsistency); - } else if (hasSubFilters && (isMultiValuedDetected == null)) { - ConvertedExpression nameConvertedExpression = convertToCouchbaseFilter(currentGenericFilter.getFilters()[0], propertiesAnnotationsMap); - return ConvertedExpression.build(nameConvertedExpression.expression().eq(buildTypedExpression(currentGenericFilter)), requiredConsistency); - } else { - Expression nameExpression; - if (hasSubFilters) { - ConvertedExpression nameConvertedExpression = convertToCouchbaseFilter(currentGenericFilter.getFilters()[0], propertiesAnnotationsMap); - nameExpression = nameConvertedExpression.expression(); - } else { - nameExpression = Expression.path(toInternalAttribute(currentGenericFilter)); - } - Expression exp1 = Expression - .par(Expression.path(nameExpression).eq(buildTypedExpression(currentGenericFilter))); - Expression exp2 = Expression - .par(Expression.path(buildTypedExpression(currentGenericFilter)).in(nameExpression)); - return ConvertedExpression.build(Expression.par(exp1.or(exp2)), requiredConsistency); - } - } - - if (FilterType.LESS_OR_EQUAL == type) { - return ConvertedExpression.build(Expression.path(Expression.path(toInternalAttribute(currentGenericFilter))).lte(buildTypedExpression(currentGenericFilter)), requiredConsistency); - } - - if (FilterType.GREATER_OR_EQUAL == type) { - return ConvertedExpression.build(Expression.path(Expression.path(toInternalAttribute(currentGenericFilter))).gte(buildTypedExpression(currentGenericFilter)), requiredConsistency); - } - - if (FilterType.PRESENCE == type) { - return ConvertedExpression.build(Expression.path(Expression.path(toInternalAttribute(currentGenericFilter))).isNotMissing(), requiredConsistency); - } - - if (FilterType.APPROXIMATE_MATCH == type) { - throw new SearchException("Convertion from APPROXIMATE_MATCH LDAP filter to Couchbase filter is not implemented"); - } - - if (FilterType.SUBSTRING == type) { - StringBuilder like = new StringBuilder(); - if (currentGenericFilter.getSubInitial() != null) { - like.append(currentGenericFilter.getSubInitial()); - } - like.append("%"); - - String[] subAny = currentGenericFilter.getSubAny(); - if ((subAny != null) && (subAny.length > 0)) { - for (String any : subAny) { - like.append(any); - like.append("%"); - } - } - - if (currentGenericFilter.getSubFinal() != null) { - like.append(currentGenericFilter.getSubFinal()); - } - return ConvertedExpression.build(Expression.path(Expression.path(toInternalAttribute(currentGenericFilter)).like(Expression.s(StringHelper.escapeJson(like.toString())))), requiredConsistency); - } - - if (FilterType.LOWERCASE == type) { - return ConvertedExpression.build(StringFunctions.lower(currentGenericFilter.getAttributeName()), requiredConsistency); - } - - throw new SearchException(String.format("Unknown filter type '%s'", type)); - } - - private String toInternalAttribute(Filter filter) { - if (ArrayHelper.isNotEmpty(filter.getFilters())) { - - - } - if (couchbaseEntryManager == null) { - return filter.getAttributeName(); - } - - return couchbaseEntryManager.toInternalAttribute(filter.getAttributeName()); - } - - private Expression buildTypedExpression(Filter currentGenericFilter) { - if (currentGenericFilter.getAssertionValue() instanceof Boolean) { - return Expression.x((Boolean) currentGenericFilter.getAssertionValue()); - } else if (currentGenericFilter.getAssertionValue() instanceof Integer) { - return Expression.x((Integer) currentGenericFilter.getAssertionValue()); - } else if (currentGenericFilter.getAssertionValue() instanceof Long) { - return Expression.x((Long) currentGenericFilter.getAssertionValue()); - } - - return Expression.s(StringHelper.escapeJson(currentGenericFilter.getAssertionValue())); - } - - private Boolean determineMultiValuedByType(String attributeName, Map propertiesAnnotationsMap) { - if ((attributeName == null) || (propertiesAnnotationsMap == null)) { - return null; - } - - if (StringHelper.equalsIgnoreCase(attributeName, CouchbaseEntryManager.OBJECT_CLASS)) { - return false; - } - - PropertyAnnotation propertyAnnotation = propertiesAnnotationsMap.get(attributeName); - if ((propertyAnnotation == null) || (propertyAnnotation.getParameterType() == null)) { - return null; - } - - Class parameterType = propertyAnnotation.getParameterType(); - - boolean isMultiValued = parameterType.equals(String[].class) || ReflectHelper.assignableFrom(parameterType, List.class) || ReflectHelper.assignableFrom(parameterType, AttributeEnum[].class); - - return isMultiValued; - } - - private boolean isRequiredConsistency(Filter filter, Map propertiesAnnotationsMap) { - if (propertiesAnnotationsMap == null) { - return false; - } - - String attributeName = filter.getAttributeName(); - PropertyAnnotation propertyAnnotation = propertiesAnnotationsMap.get(attributeName); - if ((propertyAnnotation == null) || (propertyAnnotation.getParameterType() == null)) { - return false; - } - AttributeName attributeNameAnnotation = (AttributeName) ReflectHelper.getAnnotationByType(propertyAnnotation.getAnnotations(), - AttributeName.class); - - if (attributeNameAnnotation.consistency()) { - return true; - } - - return false; - } - -} diff --git a/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/model/BucketMapping.java b/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/model/BucketMapping.java deleted file mode 100644 index 939c2f38a..000000000 --- a/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/model/BucketMapping.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2018, Gluu - */ -package org.gluu.persist.couchbase.model; - -import com.couchbase.client.java.Bucket; - -/** - * Holds bucket reference associated with it's string representation - * - * @author Yuriy Movchan Date: 05/10/2018 - */ -public class BucketMapping { - - private final String bucketName; - private final Bucket bucket; - - public BucketMapping(final String bucketName, final Bucket bucket) { - this.bucketName = bucketName; - this.bucket = bucket; - } - - public final String getBucketName() { - return bucketName; - } - - public final Bucket getBucket() { - return bucket; - } -} diff --git a/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/model/ConvertedExpression.java b/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/model/ConvertedExpression.java deleted file mode 100644 index 1f858aa33..000000000 --- a/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/model/ConvertedExpression.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.gluu.persist.couchbase.model; - -import com.couchbase.client.java.query.dsl.Expression; - -/** - * Filter to Expression convertation result - * - * @author Yuriy Movchan Date: 06/21/2019 - */ -public class ConvertedExpression { - - private Expression expression; - private boolean consistency; - - private ConvertedExpression(Expression expression) { - this.expression = expression; - } - - private ConvertedExpression(Expression expression, boolean consistency) { - this.expression = expression; - this.consistency = consistency; - } - - public static ConvertedExpression build(Expression expression, boolean consistency) { - return new ConvertedExpression(expression, consistency); - } - - public Expression expression() { - return expression; - } - - public boolean consistency() { - return consistency; - } - - public void consistency(boolean consistency) { - this.consistency = consistency; - } - - @Override - public String toString() { - return "ConvertedExpression [expression=" + expression + ", consistency=" + consistency + "]"; - } - -} diff --git a/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/model/ResultCode.java b/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/model/ResultCode.java deleted file mode 100644 index 405069891..000000000 --- a/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/model/ResultCode.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2018, Gluu - */ - -package org.gluu.persist.couchbase.model; - -import java.io.Serializable; - -/** - * This class defines a number of constants associated with result codes. - * - * @author Yuriy Movchan Date: 05/10/2018 - */ -public final class ResultCode implements Serializable { - - private static final long serialVersionUID = -9180126854928558942L; - - private ResultCode() { - } - - /** - * The integer value (0) for the "SUCCESS" result code. - */ - public static final int SUCCESS_INT_VALUE = 0; - - /** - * The integer value (1) for the "OPERATIONS_ERROR" result code. - */ - public static final int OPERATIONS_ERROR_INT_VALUE = 1; - - /** - * The integer value (48) for the "INAPPROPRIATE_AUTHENTICATION" result code. - */ - public static final int INAPPROPRIATE_AUTHENTICATION_INT_VALUE = 48; - -} diff --git a/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/model/SearchReturnDataType.java b/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/model/SearchReturnDataType.java deleted file mode 100644 index 26680ea32..000000000 --- a/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/model/SearchReturnDataType.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.gluu.persist.couchbase.model; -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2019, Gluu - */ - -import java.util.HashMap; -import java.util.Map; - -import org.gluu.persist.annotation.AttributeEnum; - -/** - * Couchbase search return data type - * - * @author Yuriy Movchan Date: 05/04/2019 - */ -public enum SearchReturnDataType implements AttributeEnum { - - SEARCH("search"), - COUNT("count"), - SEARCH_COUNT("search_count"); - - private String value; - - private static Map MAP_BY_VALUES = new HashMap(); - - static { - for (SearchReturnDataType enumType : values()) { - MAP_BY_VALUES.put(enumType.getValue(), enumType); - } - } - - SearchReturnDataType(String value) { - this.value = value; - } - - @Override - public String getValue() { - return value; - } - - public static SearchReturnDataType getByValue(String value) { - return MAP_BY_VALUES.get(value); - } - - @Override - public SearchReturnDataType resolveByValue(String value) { - return getByValue(value); - } -} diff --git a/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/operation/CouchbaseOperationService.java b/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/operation/CouchbaseOperationService.java deleted file mode 100644 index bed400b64..000000000 --- a/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/operation/CouchbaseOperationService.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - /* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2018, Gluu - */ - -package org.gluu.persist.couchbase.operation; - -import java.util.List; - -import org.gluu.persist.couchbase.impl.CouchbaseBatchOperationWraper; -import org.gluu.persist.couchbase.model.SearchReturnDataType; -import org.gluu.persist.couchbase.operation.impl.CouchbaseConnectionProvider; -import org.gluu.persist.exception.AuthenticationException; -import org.gluu.persist.exception.operation.DeleteException; -import org.gluu.persist.exception.operation.DuplicateEntryException; -import org.gluu.persist.exception.operation.EntryNotFoundException; -import org.gluu.persist.exception.operation.PersistenceException; -import org.gluu.persist.exception.operation.SearchException; -import org.gluu.persist.model.PagedResult; -import org.gluu.persist.model.SearchScope; -import org.gluu.persist.operation.PersistenceOperationService; - -import com.couchbase.client.java.document.json.JsonObject; -import com.couchbase.client.java.query.consistency.ScanConsistency; -import com.couchbase.client.java.query.dsl.Expression; -import com.couchbase.client.java.query.dsl.Sort; -import com.couchbase.client.java.subdoc.MutationSpec; - -/** - * Couchbase operation service interface - * - * @author Yuriy Movchan Date: 05/14/2018 - */ -public interface CouchbaseOperationService extends PersistenceOperationService { - - String DN = "dn"; - String UID = "uid"; - String USER_PASSWORD = "userPassword"; - String OBJECT_CLASS = "objectClass"; - - String META_DOC_ID = "meta_doc_id"; - - CouchbaseConnectionProvider getConnectionProvider(); - - boolean authenticate(String key, String password) throws SearchException, AuthenticationException; - - boolean addEntry(String key, JsonObject atts) throws DuplicateEntryException, PersistenceException; - - boolean updateEntry(String key, List mods) throws UnsupportedOperationException, PersistenceException; - - boolean delete(String key) throws EntryNotFoundException; - int delete(String key, ScanConsistency scanConsistency, Expression expression, int count) throws DeleteException; - boolean deleteRecursively(String key) throws EntryNotFoundException, SearchException; - - JsonObject lookup(String key, ScanConsistency scanConsistency, String... attributes) throws SearchException; - - PagedResult search(String key, ScanConsistency scanConsistency, Expression expression, SearchScope scope, - String[] attributes, Sort[] orderBy, CouchbaseBatchOperationWraper batchOperationWraper, SearchReturnDataType returnDataType, - int start, int count, int pageSize) throws SearchException; - - String[] createStoragePassword(String[] passwords); - - boolean isBinaryAttribute(String attribute); - boolean isCertificateAttribute(String attribute); - - boolean destroy(); - -} diff --git a/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/operation/impl/CouchbaseConnectionProvider.java b/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/operation/impl/CouchbaseConnectionProvider.java deleted file mode 100644 index ca1ddf24c..000000000 --- a/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/operation/impl/CouchbaseConnectionProvider.java +++ /dev/null @@ -1,349 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2018, Gluu - */ - -package org.gluu.persist.couchbase.operation.impl; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Properties; - -import org.gluu.persist.couchbase.model.BucketMapping; -import org.gluu.persist.couchbase.model.ResultCode; -import org.gluu.persist.exception.KeyConversionException; -import org.gluu.persist.exception.operation.ConfigurationException; -import org.gluu.persist.operation.auth.PasswordEncryptionMethod; -import org.gluu.util.ArrayHelper; -import org.gluu.util.StringHelper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.couchbase.client.core.CouchbaseException; -import com.couchbase.client.core.message.internal.PingReport; -import com.couchbase.client.core.message.internal.PingServiceHealth; -import com.couchbase.client.core.message.internal.PingServiceHealth.PingState; -import com.couchbase.client.java.Bucket; -import com.couchbase.client.java.CouchbaseCluster; -import com.couchbase.client.java.bucket.BucketInfo; -import com.couchbase.client.java.bucket.BucketManager; -import com.couchbase.client.java.env.CouchbaseEnvironment; -import com.couchbase.client.java.query.N1qlQueryResult; -import com.couchbase.client.java.query.N1qlQueryRow; -import com.couchbase.client.java.query.Select; -import com.couchbase.client.java.query.Statement; -import com.couchbase.client.java.query.dsl.Expression; - -/** - * Perform cluster initialization and open required buckets - * - * @author Yuriy Movchan Date: 05/10/2018 - */ -public class CouchbaseConnectionProvider { - - private static final Logger LOG = LoggerFactory.getLogger(CouchbaseConnectionProvider.class); - - private Properties props; - - private String[] servers; - private String[] buckets; - private String defaultBucket; - - private String userName; - private String userPassword; - - private CouchbaseEnvironment couchbaseEnvironment; - private CouchbaseCluster cluster; - private int creationResultCode; - - private HashMap bucketToBaseNameMapping; - private HashMap baseNameToBucketMapping; - private BucketMapping defaultBucketMapping; - - private ArrayList binaryAttributes, certificateAttributes; - - private PasswordEncryptionMethod passwordEncryptionMethod; - - protected CouchbaseConnectionProvider() { - } - - public CouchbaseConnectionProvider(Properties props, CouchbaseEnvironment couchbaseEnvironment) { - this.props = props; - this.couchbaseEnvironment = couchbaseEnvironment; - } - - public void create() { - try { - init(); - } catch (Exception ex) { - this.creationResultCode = ResultCode.OPERATIONS_ERROR_INT_VALUE; - - Properties clonedProperties = (Properties) props.clone(); - if (clonedProperties.getProperty("auth.userName") != null) { - clonedProperties.setProperty("auth.userPassword", "REDACTED"); - } - - LOG.error("Failed to create connection with properties: '{}'. Exception: {}", clonedProperties, ex); - ex.printStackTrace(); - } - } - - protected void init() { - this.servers = StringHelper.split(props.getProperty("servers"), ","); - - this.userName = props.getProperty("auth.userName"); - this.userPassword = props.getProperty("auth.userPassword"); - - this.defaultBucket = props.getProperty("bucket.default", null); - if (StringHelper.isEmpty(defaultBucket)) { - throw new ConfigurationException("Default bucket is not defined!"); - } - - this.buckets = StringHelper.split(props.getProperty("buckets"), ","); - if (!Arrays.asList(buckets).contains(defaultBucket)) { - this.buckets = ArrayHelper.addItemToStringArray(buckets, defaultBucket); - } - - openWithWaitImpl(); - LOG.info("Opended: '{}' buket with base names: '{}'", bucketToBaseNameMapping.keySet(), baseNameToBucketMapping.keySet()); - - if (props.containsKey("password.encryption.method")) { - this.passwordEncryptionMethod = PasswordEncryptionMethod.getMethod(props.getProperty("password.encryption.method")); - } else { - this.passwordEncryptionMethod = PasswordEncryptionMethod.HASH_METHOD_SHA256; - } - - this.binaryAttributes = new ArrayList(); - if (props.containsKey("binaryAttributes")) { - String[] binaryAttrs = StringHelper.split(props.get("binaryAttributes").toString().toLowerCase(), ","); - this.binaryAttributes.addAll(Arrays.asList(binaryAttrs)); - } - LOG.debug("Using next binary attributes: '{}'", binaryAttributes); - - this.certificateAttributes = new ArrayList(); - if (props.containsKey("certificateAttributes")) { - String[] binaryAttrs = StringHelper.split(props.get("certificateAttributes").toString().toLowerCase(), ","); - this.certificateAttributes.addAll(Arrays.asList(binaryAttrs)); - } - LOG.debug("Using next binary certificateAttributes: '{}'", certificateAttributes); - - this.creationResultCode = ResultCode.SUCCESS_INT_VALUE; - } - - private void openWithWaitImpl() { - String connectionMaxWaitTime = props.getProperty("connection.connection-max-wait-time"); - int connectionMaxWaitTimeSeconds = 30; - if (StringHelper.isNotEmpty(connectionMaxWaitTime)) { - connectionMaxWaitTimeSeconds = Integer.parseInt(connectionMaxWaitTime); - } - LOG.debug("Using Couchbase connection timeout: '{}'", connectionMaxWaitTimeSeconds); - - CouchbaseException lastException = null; - - int attempt = 0; - long currentTime = System.currentTimeMillis(); - long maxWaitTime = currentTime + connectionMaxWaitTimeSeconds * 1000; - do { - attempt++; - if (attempt > 0) { - LOG.info("Attempting to create connection: '{}'", attempt); - } - - try { - open(); - if (isConnected()) { - break; - } else { - LOG.info("Failed to connect to Couchbase"); - destory(); - } - } catch (CouchbaseException ex) { - lastException = ex; - } - - try { - Thread.sleep(5000); - } catch (InterruptedException ex) { - LOG.error("Exception happened in sleep", ex); - return; - } - currentTime = System.currentTimeMillis(); - } while (maxWaitTime > currentTime); - - if (lastException != null) { - throw lastException; - } - } - - private void open() { - this.bucketToBaseNameMapping = new HashMap(); - this.baseNameToBucketMapping = new HashMap(); - - this.cluster = CouchbaseCluster.create(couchbaseEnvironment, servers); - cluster.authenticate(userName, userPassword); - - // Open required buckets - for (String bucketName : buckets) { - String baseNamesProp = props.getProperty(String.format("bucket.%s.mapping", bucketName), ""); - String[] baseNames = StringHelper.split(baseNamesProp, ","); - - Bucket bucket = cluster.openBucket(bucketName); - - BucketMapping bucketMapping = new BucketMapping(bucketName, bucket); - - // Store in separate map to speed up search by base name - bucketToBaseNameMapping.put(bucketName, bucketMapping); - for (String baseName : baseNames) { - baseNameToBucketMapping.put(baseName, bucketMapping); - } - - if (StringHelper.equalsIgnoreCase(bucketName, defaultBucket)) { - this.defaultBucketMapping = bucketMapping; - } - } - } - - public boolean destory() { - boolean result = true; - if (bucketToBaseNameMapping != null) { - for (BucketMapping bucketMapping : bucketToBaseNameMapping.values()) { - try { - bucketMapping.getBucket().close(); - } catch (CouchbaseException ex) { - LOG.error("Failed to close bucket '{}'", bucketMapping.getBucketName(), ex); - result = false; - } - } - } - - if (cluster != null) { - result &= cluster.disconnect(); - } - - return result; - } - - public boolean isConnected() { - if (cluster == null) { - return false; - } - - boolean isConnected = true; - for (BucketMapping bucketMapping : bucketToBaseNameMapping.values()) { - try { - Bucket bucket = bucketMapping.getBucket(); - if (bucket.isClosed() || !isConnected(bucketMapping)) { - LOG.error("Bucket '{}' is invalid", bucketMapping.getBucketName()); - isConnected = false; - break; - } - } catch (CouchbaseException ex) { - LOG.error("Failed to check bucket", ex); - } - } - - return isConnected; - } - - private boolean isConnected(BucketMapping bucketMapping) { - Bucket bucket = bucketMapping.getBucket(); - - BucketManager bucketManager = bucket.bucketManager(); - BucketInfo bucketInfo = bucketManager.info(); - - boolean result = true; - if (com.couchbase.client.java.bucket.BucketType.COUCHBASE == bucketInfo.type()) { - // Check indexes state - Statement query = Select.select("state").from("system:indexes").where(Expression.path("state").eq(Expression.s("online")).not()); - N1qlQueryResult queryResult = bucket.query(query); - result = queryResult.finalSuccess(); - - if (result) { - result = queryResult.info().resultCount() == 0; - } - } - - if (result) { - PingReport pingReport = bucket.ping(); - for (PingServiceHealth pingServiceHealth : pingReport.services()) { - if (PingState.OK != pingServiceHealth.state()) { - result = false; - break; - } - } - } - - return result; - } - - public BucketMapping getBucketMapping(String baseName) { - BucketMapping bucketMapping = baseNameToBucketMapping.get(baseName); - if (bucketMapping == null) { - return null; - } - - return bucketMapping; - } - - public BucketMapping getBucketMappingByKey(String key) { - if ("_".equals(key)) { - return defaultBucketMapping; - } - - String[] baseNameParts = key.split("_"); - if (ArrayHelper.isEmpty(baseNameParts)) { - throw new KeyConversionException("Failed to determine base key part!"); - } - - BucketMapping bucketMapping = baseNameToBucketMapping.get(baseNameParts[0]); - if (bucketMapping != null) { - return bucketMapping; - } - - return defaultBucketMapping; - } - - public int getCreationResultCode() { - return creationResultCode; - } - - public boolean isCreated() { - return ResultCode.SUCCESS_INT_VALUE == creationResultCode; - } - - public String[] getServers() { - return servers; - } - - public ArrayList getBinaryAttributes() { - return binaryAttributes; - } - - public ArrayList getCertificateAttributes() { - return certificateAttributes; - } - - public boolean isBinaryAttribute(String attributeName) { - if (StringHelper.isEmpty(attributeName)) { - return false; - } - - return binaryAttributes.contains(attributeName.toLowerCase()); - } - - public boolean isCertificateAttribute(String attributeName) { - if (StringHelper.isEmpty(attributeName)) { - return false; - } - - return certificateAttributes.contains(attributeName.toLowerCase()); - } - - public PasswordEncryptionMethod getPasswordEncryptionMethod() { - return passwordEncryptionMethod; - } - -} - diff --git a/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/operation/impl/CouchbaseOperationsServiceImpl.java b/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/operation/impl/CouchbaseOperationsServiceImpl.java deleted file mode 100644 index 8cb0bae37..000000000 --- a/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/operation/impl/CouchbaseOperationsServiceImpl.java +++ /dev/null @@ -1,720 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2018, Gluu - */ - -package org.gluu.persist.couchbase.operation.impl; - -import java.time.Duration; -import java.time.Instant; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map.Entry; -import java.util.Properties; -import java.util.Set; - -import org.gluu.persist.couchbase.impl.CouchbaseBatchOperationWraper; -import org.gluu.persist.couchbase.model.BucketMapping; -import org.gluu.persist.couchbase.model.SearchReturnDataType; -import org.gluu.persist.couchbase.operation.CouchbaseOperationService; -import org.gluu.persist.couchbase.operation.watch.OperationDurationUtil; -import org.gluu.persist.exception.operation.DeleteException; -import org.gluu.persist.exception.operation.DuplicateEntryException; -import org.gluu.persist.exception.operation.EntryNotFoundException; -import org.gluu.persist.exception.operation.PersistenceException; -import org.gluu.persist.exception.operation.SearchException; -import org.gluu.persist.model.BatchOperation; -import org.gluu.persist.model.PagedResult; -import org.gluu.persist.model.SearchScope; -import org.gluu.persist.operation.auth.PasswordEncryptionHelper; -import org.gluu.util.ArrayHelper; -import org.gluu.util.StringHelper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.couchbase.client.core.CouchbaseException; -import com.couchbase.client.core.message.kv.subdoc.multi.Mutation; -import com.couchbase.client.java.Bucket; -import com.couchbase.client.java.document.JsonDocument; -import com.couchbase.client.java.document.json.JsonArray; -import com.couchbase.client.java.document.json.JsonObject; -import com.couchbase.client.java.query.Delete; -import com.couchbase.client.java.query.N1qlParams; -import com.couchbase.client.java.query.N1qlQuery; -import com.couchbase.client.java.query.N1qlQueryResult; -import com.couchbase.client.java.query.N1qlQueryRow; -import com.couchbase.client.java.query.Select; -import com.couchbase.client.java.query.Statement; -import com.couchbase.client.java.query.consistency.ScanConsistency; -import com.couchbase.client.java.query.dsl.Expression; -import com.couchbase.client.java.query.dsl.Sort; -import com.couchbase.client.java.query.dsl.path.GroupByPath; -import com.couchbase.client.java.query.dsl.path.LimitPath; -import com.couchbase.client.java.query.dsl.path.MutateLimitPath; -import com.couchbase.client.java.query.dsl.path.OffsetPath; -import com.couchbase.client.java.query.dsl.path.ReturningPath; -import com.couchbase.client.java.subdoc.DocumentFragment; -import com.couchbase.client.java.subdoc.MutateInBuilder; -import com.couchbase.client.java.subdoc.MutationSpec; - -/** - * Base service which performs all supported Couchbase operations - * - * @author Yuriy Movchan Date: 05/10/2018 - */ -public class CouchbaseOperationsServiceImpl implements CouchbaseOperationService { - - private static final Logger LOG = LoggerFactory.getLogger(CouchbaseConnectionProvider.class); - - private Properties props; - private CouchbaseConnectionProvider connectionProvider; - - private ScanConsistency scanConsistency = ScanConsistency.NOT_BOUNDED; - - private boolean ignoreAttributeScanConsistency = false; - private boolean attemptWithoutAttributeScanConsistency = true; - private boolean enableScopeSupport = false; - private boolean disableAttributeMapping = false; - - - @SuppressWarnings("unused") - private CouchbaseOperationsServiceImpl() { - } - - public CouchbaseOperationsServiceImpl(Properties props, CouchbaseConnectionProvider connectionProvider) { - this.props = props; - this.connectionProvider = connectionProvider; - init(); - } - - private void init() { - if (props.containsKey("connection.scan-consistency")) { - String scanConsistencyString = StringHelper.toUpperCase(props.get("connection.scan-consistency").toString()); - this.scanConsistency = ScanConsistency.valueOf(scanConsistencyString); - } - - if (props.containsKey("connection.ignore-attribute-scan-consistency")) { - this.ignoreAttributeScanConsistency = StringHelper.toBoolean(props.get("connection.ignore-attribute-scan-consistency").toString(), this.ignoreAttributeScanConsistency); - } - - if (props.containsKey("connection.attempt-without-attribute-scan-consistency")) { - this.attemptWithoutAttributeScanConsistency = StringHelper.toBoolean(props.get("attempt-without-attribute-scan-consistency").toString(), this.attemptWithoutAttributeScanConsistency); - } - - if (props.containsKey("connection.enable-scope-support")) { - this.enableScopeSupport = StringHelper.toBoolean(props.get("connection.enable-scope-support").toString(), this.enableScopeSupport); - } - - if (props.containsKey("connection.disable-attribute-mapping")) { - this.disableAttributeMapping = StringHelper.toBoolean(props.get("connection.disable-attribute-mapping").toString(), this.disableAttributeMapping); - } - - LOG.info("Option scanConsistency: " + scanConsistency); - LOG.info("Option ignoreAttributeScanConsistency: " + ignoreAttributeScanConsistency); - LOG.info("Option enableScopeSupport: " + enableScopeSupport); - LOG.info("Option disableAttributeMapping: " + disableAttributeMapping); - } - - @Override - public CouchbaseConnectionProvider getConnectionProvider() { - return connectionProvider; - } - - @Override - public boolean authenticate(final String key, final String password) throws SearchException { - return authenticateImpl(key, password); - } - - private boolean authenticateImpl(final String key, final String password) throws SearchException { - Instant startTime = OperationDurationUtil.instance().now(); - - boolean result = false; - if (password != null) { - JsonObject entry = lookup(key, null, USER_PASSWORD); - Object userPasswordObj = entry.get(USER_PASSWORD); - - String userPassword = null; - if (userPasswordObj instanceof JsonArray) { - userPassword = ((JsonArray) userPasswordObj).getString(0); - } else if (userPasswordObj instanceof String) { - userPassword = (String) userPasswordObj; - } - - if (userPassword != null) { - result = PasswordEncryptionHelper.compareCredentials(password.getBytes(), userPassword.getBytes()); - } - } - - Duration duration = OperationDurationUtil.instance().duration(startTime); - - BucketMapping bucketMapping = connectionProvider.getBucketMappingByKey(key); - OperationDurationUtil.instance().logDebug("Couchbase operation: bind, duration: {}, bucket: {}, key: {}", duration, bucketMapping.getBucketName(), key); - - return result; - } - - @Override - public boolean addEntry(String key, JsonObject jsonObject) throws DuplicateEntryException, PersistenceException { - Instant startTime = OperationDurationUtil.instance().now(); - - BucketMapping bucketMapping = connectionProvider.getBucketMappingByKey(key); - boolean result = addEntryImpl(bucketMapping, key, jsonObject); - - Duration duration = OperationDurationUtil.instance().duration(startTime); - OperationDurationUtil.instance().logDebug("Couchbase operation: add, duration: {}, bucket: {}, key: {}, json: {}", duration, bucketMapping.getBucketName(), key, jsonObject); - - return result; - } - - private boolean addEntryImpl(BucketMapping bucketMapping, String key, JsonObject jsonObject) throws PersistenceException { - try { - JsonDocument jsonDocument = JsonDocument.create(key, jsonObject); - JsonDocument result = bucketMapping.getBucket().upsert(jsonDocument); - if (result != null) { - return true; - } - - } catch (CouchbaseException ex) { - throw new PersistenceException("Failed to add entry", ex); - } - - return false; - } - - @Deprecated - protected boolean updateEntry(String key, JsonObject attrs) throws UnsupportedOperationException, SearchException { - List mods = new ArrayList(); - - for (Entry attrEntry : attrs.toMap().entrySet()) { - String attributeName = attrEntry.getKey(); - Object attributeValue = attrEntry.getValue(); - if (attributeName.equalsIgnoreCase(CouchbaseOperationService.OBJECT_CLASS) || attributeName.equalsIgnoreCase(CouchbaseOperationService.DN) - || attributeName.equalsIgnoreCase(CouchbaseOperationService.USER_PASSWORD)) { - continue; - } else { - if (attributeValue != null) { - mods.add(new MutationSpec(Mutation.REPLACE, attributeName, attributeValue)); - } - } - } - - return updateEntry(key, mods); - } - - @Override - public boolean updateEntry(String key, List mods) throws UnsupportedOperationException, SearchException { - Instant startTime = OperationDurationUtil.instance().now(); - - BucketMapping bucketMapping = connectionProvider.getBucketMappingByKey(key); - boolean result = updateEntryImpl(bucketMapping, key, mods); - - Duration duration = OperationDurationUtil.instance().duration(startTime); - OperationDurationUtil.instance().logDebug("Couchbase operation: modify, duration: {}, bucket: {}, key: {}, mods: {}", duration, bucketMapping.getBucketName(), key, mods); - - return result; - } - - private boolean updateEntryImpl(BucketMapping bucketMapping, String key, List mods) throws SearchException { - try { - MutateInBuilder builder = bucketMapping.getBucket().mutateIn(key); - - return modifyEntry(builder, mods); - } catch (final CouchbaseException ex) { - throw new SearchException("Failed to update entry", ex); - } - } - - protected boolean modifyEntry(MutateInBuilder builder, List mods) throws UnsupportedOperationException, SearchException { - try { - for (MutationSpec mod : mods) { - Mutation type = mod.type(); - if (Mutation.DICT_ADD == type) { - builder.insert(mod.path(), mod.fragment()); - } else if (Mutation.REPLACE == type) { - builder.replace(mod.path(), mod.fragment()); - } else if (Mutation.DELETE == type) { - builder.remove(mod.path()); - } else { - throw new UnsupportedOperationException("Operation type '" + type + "' is not implemented"); - } - } - - DocumentFragment result = builder.execute(); - if (result.size() > 0) { - return result.status(0).isSuccess(); - } - - return false; - } catch (final CouchbaseException ex) { - throw new SearchException("Failed to update entry", ex); - } - } - - @Override - public boolean delete(String key) throws EntryNotFoundException { - Instant startTime = OperationDurationUtil.instance().now(); - - BucketMapping bucketMapping = connectionProvider.getBucketMappingByKey(key); - boolean result = deleteImpl(bucketMapping, key); - - Duration duration = OperationDurationUtil.instance().duration(startTime); - OperationDurationUtil.instance().logDebug("Couchbase operation: delete, duration: {}, bucket: {}, key: {}", duration, bucketMapping.getBucketName(), key); - - return result; - } - - private boolean deleteImpl(BucketMapping bucketMapping, String key) throws EntryNotFoundException { - try { - JsonDocument result = bucketMapping.getBucket().remove(key); - - return (result != null) && (result.id() != null); - } catch (CouchbaseException ex) { - throw new EntryNotFoundException("Failed to delete entry", ex); - } - } - - @Override - public int delete(String key, ScanConsistency scanConsistency, Expression expression, int count) throws DeleteException { - Instant startTime = OperationDurationUtil.instance().now(); - - BucketMapping bucketMapping = connectionProvider.getBucketMappingByKey(key); - ScanConsistency useScanConsistency = getScanConsistency(scanConsistency, false); - - int result = deleteImpl(bucketMapping, key, useScanConsistency, expression, count); - - String attemptInfo = getScanAttemptLogInfo(scanConsistency, useScanConsistency, false); - - Duration duration = OperationDurationUtil.instance().duration(startTime); - OperationDurationUtil.instance().logDebug("Couchbase operation: delete_search, duration: {}, bucket: {}, key: {}, expression: {}, count: {}, consistency: {}{}", duration, bucketMapping.getBucketName(), key, expression, count, useScanConsistency, attemptInfo); - - return result; - } - - private int deleteImpl(BucketMapping bucketMapping, String key, ScanConsistency scanConsistency, Expression expression, int count) throws DeleteException { - Bucket bucket = bucketMapping.getBucket(); - - Expression finalExpression = expression; - if (enableScopeSupport) { - Expression scopeExpression = Expression.path("META().id").like(Expression.s(key + "%")); - finalExpression = scopeExpression.and(expression); - } - - MutateLimitPath deleteQuery = Delete.deleteFrom(Expression.i(bucketMapping.getBucketName())).where(finalExpression); - ReturningPath query = deleteQuery.limit(count); - LOG.debug("Execution query: '" + query + "'"); - - N1qlQueryResult result = bucket.query(N1qlQuery.simple(query, N1qlParams.build().consistency(scanConsistency))); - if (!result.finalSuccess()) { - throw new DeleteException(String.format("Failed to delete entries. Query: '%s'. Error: '%s', Error count: '%d'", query, result.errors(), - result.info().errorCount()), result.errors().get(0).getInt("code")); - } - - return result.info().mutationCount(); - } - - @Override - public boolean deleteRecursively(String key) throws EntryNotFoundException, SearchException { - Instant startTime = OperationDurationUtil.instance().now(); - - BucketMapping bucketMapping = connectionProvider.getBucketMappingByKey(key); - boolean result = deleteRecursivelyImpl(bucketMapping, key); - - Duration duration = OperationDurationUtil.instance().duration(startTime); - OperationDurationUtil.instance().logDebug("Couchbase operation: delete_tree, duration: {}, bucket: {}, key: {}", duration, bucketMapping.getBucketName(), key); - - return result; - } - - private boolean deleteRecursivelyImpl(BucketMapping bucketMapping, String key) throws SearchException, EntryNotFoundException { - try { - if (enableScopeSupport) { - MutateLimitPath deleteQuery = Delete.deleteFrom(Expression.i(bucketMapping.getBucketName())) - .where(Expression.path("META().id").like(Expression.s(key + "%"))); - - N1qlQueryResult result = bucketMapping.getBucket().query(deleteQuery); - if (!result.finalSuccess()) { - throw new SearchException(String.format("Failed to delete entries. Query: '%s'. Error: '%s', Error count: '%d'", deleteQuery, result.errors(), - result.info().errorCount()), result.errors().get(0).getInt("code")); - } - } else { - LOG.warn("Removing only base key without sub-tree: " + key); - delete(key); - } - - return true; - } catch (CouchbaseException ex) { - throw new EntryNotFoundException("Failed to delete entry", ex); - } - } - - @Override - public JsonObject lookup(String key, ScanConsistency scanConsistency, String... attributes) throws SearchException { - Instant startTime = OperationDurationUtil.instance().now(); - - BucketMapping bucketMapping = connectionProvider.getBucketMappingByKey(key); - - boolean secondTry = false; - ScanConsistency useScanConsistency = getScanConsistency(scanConsistency, attemptWithoutAttributeScanConsistency); - JsonObject result = null; - SearchException lastException = null; - try { - result = lookupImpl(bucketMapping, key, useScanConsistency, attributes); - } catch (SearchException ex) { - lastException = ex; - } - if ((result == null) || result.isEmpty()) { - ScanConsistency useScanConsistency2 = getScanConsistency(scanConsistency, false); - if (!useScanConsistency2.equals(useScanConsistency)) { - useScanConsistency = useScanConsistency2; - secondTry = true; - result = lookupImpl(bucketMapping, key, useScanConsistency, attributes); - } else { - if (lastException != null) { - throw lastException; - } - } - } - - String attemptInfo = getScanAttemptLogInfo(scanConsistency, useScanConsistency, secondTry); - - Duration duration = OperationDurationUtil.instance().duration(startTime); - OperationDurationUtil.instance().logDebug("Couchbase operation: lookup, duration: {}, bucket: {}, key: {}, attributes: {}, consistency: {}{}", duration, bucketMapping.getBucketName(), key, attributes, useScanConsistency, attemptInfo); - - return result; - } - - private JsonObject lookupImpl(BucketMapping bucketMapping, String key, ScanConsistency scanConsistency, String... attributes) throws SearchException { - try { - Bucket bucket = bucketMapping.getBucket(); - if (ArrayHelper.isEmpty(attributes)) { - JsonDocument doc = bucket.get(key); - if (doc != null) { - return doc.content(); - } - - } else { - JsonDocument doc = bucket.get(key); - if (doc != null) { - Set docAtributesKeep = new HashSet(Arrays.asList(attributes)); - - for (Iterator it = doc.content().getNames().iterator(); it.hasNext();) { - String docAtribute = (String) it.next(); - if (!docAtributesKeep.contains(docAtribute)) { - it.remove(); - } - } - - return doc.content(); - } - -// N1qlParams params = N1qlParams.build().consistency(scanConsistency); -// OffsetPath select = Select.select(attributes).from(Expression.i(bucketMapping.getBucketName())).useKeys(Expression.s(key)).limit(1); -// N1qlQueryResult result = bucket.query(N1qlQuery.simple(select, params)); -// if (!result.finalSuccess()) { -// throw new SearchException(String.format("Failed to lookup entry. Errors: %s", result.errors()), result.info().errorCount()); -// } -// -// if (result.allRows().size() == 1) { -// return result.allRows().get(0).value(); -// } - - } - } catch (CouchbaseException ex) { - throw new SearchException("Failed to lookup entry", ex); - } - - throw new SearchException("Failed to lookup entry"); - } - - @Override - public PagedResult search(String key, ScanConsistency scanConsistency, Expression expression, SearchScope scope, String[] attributes, Sort[] orderBy, - CouchbaseBatchOperationWraper batchOperationWraper, SearchReturnDataType returnDataType, int start, int count, int pageSize) throws SearchException { - Instant startTime = OperationDurationUtil.instance().now(); - - BucketMapping bucketMapping = connectionProvider.getBucketMappingByKey(key); - - boolean secondTry = false; - ScanConsistency useScanConsistency = getScanConsistency(scanConsistency, attemptWithoutAttributeScanConsistency); - PagedResult result = null; - int attemps = 20; - do { - attemps--; - try { - result = searchImpl(bucketMapping, key, useScanConsistency, expression, scope, attributes, orderBy, batchOperationWraper, - returnDataType, start, count, pageSize); - break; - } catch (SearchException ex) { - if (ex.getErrorCode() != 5000) { - throw ex; - } - - LOG.warn("Waiting for Indexer Warmup..."); - try { - Thread.sleep(2000); - } catch (InterruptedException ex2) {} - } - } while (attemps > 0); - if ((result == null) || (result.getEntriesCount() == 0)) { - ScanConsistency useScanConsistency2 = getScanConsistency(scanConsistency, false); - if (!useScanConsistency2.equals(useScanConsistency)) { - useScanConsistency = useScanConsistency2; - result = searchImpl(bucketMapping, key, useScanConsistency, expression, scope, attributes, orderBy, batchOperationWraper, returnDataType, start, count, pageSize); - secondTry = true; - } - } - - String attemptInfo = getScanAttemptLogInfo(scanConsistency, useScanConsistency, secondTry); - - Duration duration = OperationDurationUtil.instance().duration(startTime); - OperationDurationUtil.instance().logDebug("Couchbase operation: search, duration: {}, bucket: {}, key: {}, expression: {}, scope: {}, attributes: {}, orderBy: {}, batchOperationWraper: {}, returnDataType: {}, start: {}, count: {}, pageSize: {}, consistency: {}{}", duration, bucketMapping.getBucketName(), key, expression, scope, attributes, orderBy, batchOperationWraper, returnDataType, start, count, pageSize, useScanConsistency, attemptInfo); - - return result; - } - - private PagedResult searchImpl(BucketMapping bucketMapping, String key, ScanConsistency scanConsistency, Expression expression, SearchScope scope, String[] attributes, Sort[] orderBy, - CouchbaseBatchOperationWraper batchOperationWraper, SearchReturnDataType returnDataType, int start, int count, int pageSize) throws SearchException { - Bucket bucket = bucketMapping.getBucket(); - - BatchOperation ldapBatchOperation = null; - if (batchOperationWraper != null) { - ldapBatchOperation = (BatchOperation) batchOperationWraper.getBatchOperation(); - } - - if (LOG.isTraceEnabled()) { - // Find whole DB search - if (StringHelper.equalsIgnoreCase(key, "_")) { - LOG.trace("Search in whole DB tree", new Exception()); - } - } - - Expression finalExpression = expression; - if (enableScopeSupport) { - Expression scopeExpression; - if (scope == null) { - scopeExpression = null; - } else if (SearchScope.BASE == scope) { - scopeExpression = Expression.path("META().id").like(Expression.s(key + "%")) - .and(Expression.path("META().id").notLike(Expression.s(key + "\\\\_%\\\\_"))); - } else { - scopeExpression = Expression.path("META().id").like(Expression.s(key + "%")); - } - - if (scopeExpression != null) { - finalExpression = scopeExpression.and(expression); - } - } else { - if (scope != null) { - LOG.debug("Ignoring scope '" + scope + " for expression: " + expression); - } - } - - String[] select = attributes; - if (select == null) { - select = new String[] { "gluu_doc.*", CouchbaseOperationService.DN }; - } else if ((select.length == 1) && StringHelper.isEmpty(select[0])) { - // Compatibility with Couchbase persistence layer when application pass filter new String[] { "" } - select = new String[] { CouchbaseOperationService.DN }; - } else { - boolean hasDn = Arrays.asList(select).contains(CouchbaseOperationService.DN); - if (!hasDn) { - select = ArrayHelper.arrayMerge(select, new String[] { CouchbaseOperationService.DN }); - } - } - GroupByPath selectQuery = Select.select(select).from(Expression.i(bucketMapping.getBucketName())).as("gluu_doc").where(finalExpression); - - LimitPath baseQuery = selectQuery; - if (orderBy != null) { - baseQuery = selectQuery.orderBy(orderBy); - } - - List searchResultList = new ArrayList(); - - if ((SearchReturnDataType.SEARCH == returnDataType) || (SearchReturnDataType.SEARCH_COUNT == returnDataType)) { - N1qlQueryResult lastResult = null; - if (pageSize > 0) { - boolean collectSearchResult; - - Statement query = null; - int currentLimit; - try { - List lastSearchResultList; - int resultCount = 0; - do { - collectSearchResult = true; - - currentLimit = pageSize; - if (count > 0) { - currentLimit = Math.min(pageSize, count - resultCount); - } - - query = baseQuery.limit(currentLimit).offset(start + resultCount); - LOG.debug("Execution query: '" + query + "'"); - lastResult = bucket.query(N1qlQuery.simple(query, N1qlParams.build().consistency(scanConsistency))); - if (!lastResult.finalSuccess()) { - throw new SearchException(String.format("Failed to search entries. Query: '%s'. Error: '%s', Error count: '%d'", query, lastResult.errors(), - lastResult.info().errorCount()), lastResult.errors().get(0).getInt("code")); - } - - lastSearchResultList = lastResult.allRows(); - - if (ldapBatchOperation != null) { - collectSearchResult = ldapBatchOperation.collectSearchResult(lastSearchResultList.size()); - } - if (collectSearchResult) { - searchResultList.addAll(lastSearchResultList); - } - - if (ldapBatchOperation != null) { - List entries = batchOperationWraper.createEntities(lastSearchResultList); - ldapBatchOperation.performAction(entries); - } - - resultCount += lastSearchResultList.size(); - - if ((count > 0) && (resultCount >= count)) { - break; - } - } while (lastSearchResultList.size() > 0); - } catch (CouchbaseException ex) { - throw new SearchException("Failed to search entries. Query: '" + query + "'", ex); - } - } else { - try { - Statement query = baseQuery; - if (count > 0) { - query = ((LimitPath) query).limit(count); - } - if (start > 0) { - query = ((OffsetPath) query).offset(start); - } - - LOG.debug("Execution query: '" + query + "'"); - lastResult = bucket.query(N1qlQuery.simple(query, N1qlParams.build().consistency(scanConsistency))); - if (!lastResult.finalSuccess()) { - throw new SearchException(String.format("Failed to search entries. Query: '%s'. Error: '%s', Error count: '%d'", baseQuery, lastResult.errors(), - lastResult.info().errorCount()), lastResult.errors().get(0).getInt("code")); - } - - searchResultList.addAll(lastResult.allRows()); - } catch (CouchbaseException ex) { - throw new SearchException("Failed to search entries. Query: '" + baseQuery.toString() + "'", ex); - } - } - } - - List resultRows = new ArrayList(searchResultList.size()); - for (N1qlQueryRow row : searchResultList) { - resultRows.add(row.value()); - } - - PagedResult result = new PagedResult(); - result.setEntries(resultRows); - result.setEntriesCount(resultRows.size()); - result.setStart(start); - - if ((SearchReturnDataType.COUNT == returnDataType) || (SearchReturnDataType.SEARCH_COUNT == returnDataType)) { - GroupByPath selectCountQuery = Select.select("COUNT(*) as TOTAL").from(Expression.i(bucketMapping.getBucketName())) - .where(finalExpression); - try { - LOG.debug("Calculating count. Execution query: '" + selectCountQuery + "'"); - N1qlQueryResult countResult = bucket.query(N1qlQuery.simple(selectCountQuery, N1qlParams.build().consistency(scanConsistency))); - if (!countResult.finalSuccess() || (countResult.info().resultCount() != 1)) { - throw new SearchException(String.format("Failed to calculate count entries. Query: '%s'. Error: '%s', Error count: '%d'", selectCountQuery, countResult.errors(), - countResult.info().errorCount()), countResult.errors().get(0).getInt("code")); - } - result.setTotalEntriesCount(countResult.allRows().get(0).value().getInt("TOTAL")); - } catch (CouchbaseException ex) { - throw new SearchException("Failed to calculate count entries. Query: '" + selectCountQuery.toString() + "'", ex); - } - } - - return result; - } - - public String[] createStoragePassword(String[] passwords) { - if (ArrayHelper.isEmpty(passwords)) { - return passwords; - } - - String[] results = new String[passwords.length]; - for (int i = 0; i < passwords.length; i++) { - results[i] = PasswordEncryptionHelper.createStoragePassword(passwords[i], connectionProvider.getPasswordEncryptionMethod()); - } - - return results; - } - - @Override - public boolean isBinaryAttribute(String attribute) { - return this.connectionProvider.isBinaryAttribute(attribute); - } - - @Override - public boolean isCertificateAttribute(String attribute) { - return this.connectionProvider.isCertificateAttribute(attribute); - } - - private ScanConsistency getScanConsistency(ScanConsistency operationScanConsistency, boolean ignore) { - if (ignore) { - return scanConsistency; - } - - if (ignoreAttributeScanConsistency) { - return scanConsistency; - } - - if (operationScanConsistency != null) { - return operationScanConsistency; - } - - return scanConsistency; - } - - public ScanConsistency getScanConsistency() { - return scanConsistency; - } - - public boolean isDisableAttributeMapping() { - return disableAttributeMapping; - } - - @Override - public boolean destroy() { - boolean result = true; - - if (connectionProvider != null) { - try { - connectionProvider.destory(); - } catch (Exception ex) { - LOG.error("Failed to destory provider correctly"); - result = false; - } - } - - return result; - } - - @Override - public boolean isConnected() { - return connectionProvider.isConnected(); - } - - protected String getScanAttemptLogInfo(ScanConsistency scanConsistency, ScanConsistency usedScanConsistency, boolean secondTry) { - String attemptInfo = ""; - if (secondTry) { - attemptInfo = ", attempt: second"; - } else { - ScanConsistency useScanConsistency2 = getScanConsistency(scanConsistency, false); - if (!useScanConsistency2.equals(usedScanConsistency)) { - attemptInfo = ", attempt: first"; - } - } - - return attemptInfo; - } - -} diff --git a/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/operation/watch/OperationDurationUtil.java b/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/operation/watch/OperationDurationUtil.java deleted file mode 100644 index 6554c96c5..000000000 --- a/persistence-couchbase/src/main/java/org/gluu/persist/couchbase/operation/watch/OperationDurationUtil.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.gluu.persist.couchbase.operation.watch; - -import org.gluu.persist.watch.DurationUtil; - -/** - * Simple Couchbase operation duration calculator helper - * - * @author Yuriy Movchan Date: 04/08/2019 - */ -public class OperationDurationUtil extends DurationUtil { - - private static OperationDurationUtil instance = new OperationDurationUtil(); - - public static DurationUtil instance() { - return instance; - } - - public void logDebug(String format, Object... arguments) { - if (log.isDebugEnabled()) { - log.debug(format, arguments); - } - } - -} diff --git a/persistence-couchbase/src/test/java/org/gluu/test/.gitignore b/persistence-couchbase/src/test/java/org/gluu/test/.gitignore deleted file mode 100644 index 4a5e93275..000000000 --- a/persistence-couchbase/src/test/java/org/gluu/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/dev/ diff --git a/persistence-couchbase/src/test/java/org/gluu/test/dev/.gitignore b/persistence-couchbase/src/test/java/org/gluu/test/dev/.gitignore deleted file mode 100644 index c06add60c..000000000 --- a/persistence-couchbase/src/test/java/org/gluu/test/dev/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/TestCouchbaseOperationsService.java diff --git a/persistence-filter/pom.xml b/persistence-filter/pom.xml deleted file mode 100644 index 432621dce..000000000 --- a/persistence-filter/pom.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - 4.0.0 - oxcore-persistence-filter - jar - persistence-filter - - - org.gluu - oxcore - 4.0.0-SNAPSHOT - - - - - ${project.groupId} - oxcore-util - ${project.version} - - - - \ No newline at end of file diff --git a/persistence-filter/src/main/java/org/gluu/search/filter/Filter.java b/persistence-filter/src/main/java/org/gluu/search/filter/Filter.java deleted file mode 100644 index c8b203be1..000000000 --- a/persistence-filter/src/main/java/org/gluu/search/filter/Filter.java +++ /dev/null @@ -1,270 +0,0 @@ -package org.gluu.search.filter; - -import java.util.List; - -import org.gluu.util.ArrayHelper; - -/** - * Simple filter without dependency to specific persistence filter mechanism - * - * @author Yuriy Movchan Date: 2017/12/12 - */ -public class Filter { - - private FilterType type; - - private Filter[] filters; - - private String filterString; - private String attributeName; - private Object assertionValue; - - private String subInitial; - private String[] subAny; - private String subFinal; - - private Boolean multiValued; - - public Filter(FilterType type) { - this.type = type; - } - - public Filter(FilterType type, Filter... filters) { - this(type); - this.filters = filters; - } - - public Filter(FilterType type, String filterString) { - this(type); - this.filterString = filterString; - } - - public Filter(FilterType type, Filter filter, Object assertionValue) { - this(type); - this.filters = new Filter[] { filter }; - this.assertionValue = assertionValue; - } - - public Filter(FilterType type, String attributeName, Object assertionValue) { - this(type); - this.attributeName = attributeName; - this.assertionValue = assertionValue; - } - - public Filter(FilterType type, String attributeName, String subInitial, String[] subAny, String subFinal) { - this(type); - this.attributeName = attributeName; - this.subInitial = subInitial; - this.subAny = subAny; - this.subFinal = subFinal; - } - - /* - * This method force filter to use specific syntax. It's not useful when we need - * to support different persistent mechanisms - */ - @Deprecated - public static Filter create(final String filterString) { - return new Filter(FilterType.RAW, filterString); - } - - public static Filter createPresenceFilter(final String attributeName) { - return new Filter(FilterType.PRESENCE, attributeName, null); - } - - public static Filter createEqualityFilter(final String attributeName, final Object assertionValue) { - return new Filter(FilterType.EQUALITY, attributeName, assertionValue); - } - - public static Filter createEqualityFilter(final Filter filter, final Object assertionValue) { - return new Filter(FilterType.EQUALITY, filter, assertionValue); - } - - public static Filter createNOTFilter(final Filter filter) { - return new Filter(FilterType.NOT, filter); - } - - public static Filter createLowercaseFilter(final String attributeName) { - return new Filter(FilterType.LOWERCASE, attributeName, null); - } - - public static Filter createLessOrEqualFilter(final String attributeName, final Object assertionValue) { - return new Filter(FilterType.LESS_OR_EQUAL, attributeName, assertionValue); - } - - public static Filter createGreaterOrEqualFilter(final String attributeName, final Object assertionValue) { - return new Filter(FilterType.GREATER_OR_EQUAL, attributeName, assertionValue); - } - - public static Filter createApproximateMatchFilter(final String attributeName, final String assertionValue) { - return new Filter(FilterType.APPROXIMATE_MATCH, attributeName, assertionValue); - } - - public static Filter createSubstringFilter(final String attributeName, final String subInitial, - final String[] subAny, final String subFinal) { - return new Filter(FilterType.SUBSTRING, attributeName, subInitial, subAny, subFinal); - } - - public static Filter createORFilter(final Filter... filters) { - return new Filter(FilterType.OR, filters); - } - - public static Filter createORFilter(final List filters) { - return new Filter(FilterType.OR, filters.toArray(new Filter[0])); - } - - public static Filter createANDFilter(final Filter... filters) { - return new Filter(FilterType.AND, filters); - } - - public static Filter createANDFilter(final List filters) { - return new Filter(FilterType.AND, filters.toArray(new Filter[0])); - } - - public final FilterType getType() { - return type; - } - - public final void setType(FilterType type) { - this.type = type; - } - - public final Filter[] getFilters() { - return filters; - } - - public final void setFilters(Filter[] filters) { - this.filters = filters; - } - - public final String getFilterString() { - return filterString; - } - - public final void setFilterString(String filterString) { - this.filterString = filterString; - } - - public final String getAttributeName() { - return attributeName; - } - - public final void setAttributeName(String attributeName) { - this.attributeName = attributeName; - } - - public final Object getAssertionValue() { - return assertionValue; - } - - public final void setAssertionValue(Object assertionValue) { - this.assertionValue = assertionValue; - } - - public final String getSubInitial() { - return subInitial; - } - - public final void setSubInitial(String subInitial) { - this.subInitial = subInitial; - } - - public final String[] getSubAny() { - return subAny; - } - - public final void setSubAny(String[] subAny) { - this.subAny = subAny; - } - - public final String getSubFinal() { - return subFinal; - } - - public final void setSubFinal(String subFinal) { - this.subFinal = subFinal; - } - - public final Boolean getMultiValued() { - return multiValued; - } - - public Filter multiValued() { - this.multiValued = Boolean.TRUE; - return this; - } - - public Filter multiValued(Boolean multiValued) { - this.multiValued = multiValued; - return this; - } - - @Override - public String toString() { - if (FilterType.RAW == this.type) { - return this.filterString; - } - - StringBuilder sb = new StringBuilder("("); - - if ((FilterType.NOT == this.type) || (FilterType.AND == this.type) || (FilterType.OR == this.type)) { - if (this.filters != null) { - sb.append(this.type.getSign()); - for (Filter filter : filters) { - sb.append(filter.toString()); - } - sb.append(")"); - - return sb.toString(); - } - } - if ((FilterType.EQUALITY == this.type) || (FilterType.LESS_OR_EQUAL == this.type) - || (FilterType.GREATER_OR_EQUAL == this.type)) { - if (ArrayHelper.isNotEmpty(this.filters)) { - return sb.append(this.filters[0].toString()).append(this.type.getSign()).append(this.assertionValue).append(')') - .toString(); - } else { - return sb.append(this.attributeName).append(this.type.getSign()).append(this.assertionValue).append(')') - .toString(); - } - } - - if (FilterType.PRESENCE == this.type) { - return sb.append(this.attributeName).append("=").append(this.type.getSign()).append(')').toString(); - } - - if (FilterType.APPROXIMATE_MATCH == this.type) { - return sb.append(this.attributeName).append(this.type.getSign()).append("=").append(this.assertionValue) - .append(')').toString(); - } - - if (FilterType.SUBSTRING == this.type) { - sb.append(this.attributeName).append(this.type.getSign()); - if (this.subInitial != null) { - sb.append(this.subInitial); - sb.append('*'); - } - if (this.subAny != null) { - sb.append('*'); - for (final String s : subAny) { - sb.append(s); - sb.append('*'); - } - } - if (this.subFinal != null) { - sb.append('*'); - sb.append(this.subFinal); - } - sb.append(')'); - - return sb.toString().replaceAll("\\*\\*","*"); - } - - if (FilterType.LOWERCASE == this.type) { - return sb.append("lower(\"").append(this.attributeName).append("\")").toString(); - } - - return super.toString(); - } - -} diff --git a/persistence-filter/src/main/java/org/gluu/search/filter/FilterType.java b/persistence-filter/src/main/java/org/gluu/search/filter/FilterType.java deleted file mode 100644 index b0a0cda98..000000000 --- a/persistence-filter/src/main/java/org/gluu/search/filter/FilterType.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.gluu.search.filter; - -/** - * Filter operation types - * - * @author Yuriy Movchan Date: 2017/12/13 - */ -public enum FilterType { - - RAW(""), PRESENCE("*"), EQUALITY("="), LESS_OR_EQUAL("<="), GREATER_OR_EQUAL(">="), APPROXIMATE_MATCH("~"), SUBSTRING("="), NOT("!"), - OR("|"), AND("&"), LOWERCASE("lowercase"); - - private String sign; - - FilterType(String sign) { - this.sign = sign; - } - - public final String getSign() { - return sign; - } - -} diff --git a/persistence-hybrid/pom.xml b/persistence-hybrid/pom.xml deleted file mode 100644 index f3eb94689..000000000 --- a/persistence-hybrid/pom.xml +++ /dev/null @@ -1,59 +0,0 @@ - - - 4.0.0 - oxcore-persistence-hybrid - jar - persistence-hybrid - - - org.gluu - oxcore - 4.0.0-SNAPSHOT - - - - - - src/main/resources - true - - **/*.xml - **/services/* - **/*.properties - - - - - - - - - ${project.groupId} - oxcore-util - ${project.version} - - - ${project.groupId} - oxcore-persistence-core - ${project.version} - - - ${project.groupId} - oxcore-persistence-cdi - ${project.version} - - - - - javax.enterprise - cdi-api - provided - - - javax.inject - javax.inject - - - - - \ No newline at end of file diff --git a/persistence-hybrid/src/main/java/org/gluu/persist/hybrid/impl/HybridEntryManager.java b/persistence-hybrid/src/main/java/org/gluu/persist/hybrid/impl/HybridEntryManager.java deleted file mode 100644 index 973b4dd8b..000000000 --- a/persistence-hybrid/src/main/java/org/gluu/persist/hybrid/impl/HybridEntryManager.java +++ /dev/null @@ -1,416 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.hybrid.impl; - -import java.io.Serializable; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Properties; - -import org.gluu.persist.PersistenceEntryManager; -import org.gluu.persist.event.DeleteNotifier; -import org.gluu.persist.exception.KeyConversionException; -import org.gluu.persist.exception.MappingException; -import org.gluu.persist.exception.operation.ConfigurationException; -import org.gluu.persist.exception.operation.DeleteException; -import org.gluu.persist.impl.BaseEntryManager; -import org.gluu.persist.key.impl.GenericKeyConverter; -import org.gluu.persist.key.impl.model.ParsedKey; -import org.gluu.persist.model.AttributeData; -import org.gluu.persist.model.AttributeDataModification; -import org.gluu.persist.model.BatchOperation; -import org.gluu.persist.model.PagedResult; -import org.gluu.persist.model.SearchScope; -import org.gluu.persist.model.SortOrder; -import org.gluu.persist.reflect.property.PropertyAnnotation; -import org.gluu.search.filter.Filter; -import org.gluu.util.ArrayHelper; -import org.gluu.util.StringHelper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Hybrid Entry Manager - * - * @author Yuriy Movchan Date: 07/10/2019 - */ -public class HybridEntryManager extends BaseEntryManager implements Serializable { - - private static final long serialVersionUID = -1544664410881103105L; - - private static final Logger LOG = LoggerFactory.getLogger(HybridEntryManager.class); - - private static final GenericKeyConverter KEY_CONVERTER = new GenericKeyConverter(); - - private Properties mappingProperties; - private HashMap persistenceEntryManagers; - private HybridPersistenceOperationService operationService; - - private PersistenceEntryManager defaultPersistenceEntryManager; - private HashMap baseNameToEntryManagerMapping; - - public HybridEntryManager() { - } - - public HybridEntryManager(Properties mappingProperties, HashMap persistenceEntryManagers, HybridPersistenceOperationService operationService) { - this.mappingProperties = mappingProperties; - this.persistenceEntryManagers = persistenceEntryManagers; - this.operationService = operationService; - - init(); - } - - protected void init() { - String defaultPersistenceType = mappingProperties.getProperty("storage.default", null); - if (StringHelper.isEmpty(defaultPersistenceType) || (persistenceEntryManagers.get(defaultPersistenceType) == null)) { - throw new ConfigurationException("Default persistence type is not defined!"); - } - this.defaultPersistenceEntryManager = persistenceEntryManagers.get(defaultPersistenceType); - - this.baseNameToEntryManagerMapping = new HashMap(); - for (Entry persistenceTypeEntry : persistenceEntryManagers.entrySet()) { - String mapping = mappingProperties.getProperty(String.format("storage.%s.mapping", persistenceTypeEntry.getKey()), ""); - String[] baseNames = StringHelper.split(mapping, ","); - for (String baseName : baseNames) { - baseNameToEntryManagerMapping.put(baseName, persistenceTypeEntry.getValue()); - } - } - } - - @Override - public void addDeleteSubscriber(DeleteNotifier subscriber) { - if (this.persistenceEntryManagers == null) { - return; - } - - for (PersistenceEntryManager persistenceEntryManager : persistenceEntryManagers.values()) { - persistenceEntryManager.addDeleteSubscriber(subscriber); - } - } - - @Override - public boolean authenticate(String bindDn, String password) { - PersistenceEntryManager persistenceEntryManager = getEntryManagerForDn(bindDn); - return persistenceEntryManager.authenticate(bindDn, password); - } - - @Override - public boolean authenticate(String baseDN, String userName, String password) { - PersistenceEntryManager persistenceEntryManager = getEntryManagerForDn(baseDN); - return persistenceEntryManager.authenticate(baseDN, userName, password); - } - - @Override - public boolean contains(Object entry) { - Class entryClass = entry.getClass(); - Object dnValue = getDNValue(entry, entryClass); - - PersistenceEntryManager persistenceEntryManager = getEntryManagerForDn(dnValue); - return persistenceEntryManager.contains(entry); - } - - @Override - public boolean contains(String primaryKey, Class entryClass) { - PersistenceEntryManager persistenceEntryManager = getEntryManagerForDn(primaryKey); - return persistenceEntryManager.contains(primaryKey, entryClass); - } - @Override - public boolean contains(String baseDN, Class entryClass, Filter filter) { - PersistenceEntryManager persistenceEntryManager = getEntryManagerForDn(baseDN); - return persistenceEntryManager.contains(baseDN, entryClass, filter); - } - - @Override - public int countEntries(Object entry) { - Class entryClass = entry.getClass(); - Object dnValue = getDNValue(entry, entryClass); - - PersistenceEntryManager persistenceEntryManager = getEntryManagerForDn(dnValue); - return persistenceEntryManager.countEntries(entry); - } - - @Override - public int countEntries(String baseDN, Class entryClass, Filter filter) { - PersistenceEntryManager persistenceEntryManager = getEntryManagerForDn(baseDN); - return persistenceEntryManager.countEntries(baseDN, entryClass, filter); - } - - @Override - public int countEntries(String baseDN, Class entryClass, Filter filter, SearchScope scope) { - PersistenceEntryManager persistenceEntryManager = getEntryManagerForDn(baseDN); - return persistenceEntryManager.countEntries(baseDN, entryClass, filter, scope); - } - - @Override - public Date decodeTime(String baseDN, String date) { - PersistenceEntryManager persistenceEntryManager = getEntryManagerForDn(baseDN); - return persistenceEntryManager.decodeTime(baseDN, date); - } - - @Override - public boolean destroy() { - if (this.persistenceEntryManagers == null) { - return true; - } - - boolean result = true; - for (PersistenceEntryManager persistenceEntryManager : persistenceEntryManagers.values()) { - try { - result &= persistenceEntryManager.destroy(); - } catch (Exception ex) { - LOG.error("Faild to destroy Persistence Entry Manager", ex); - } - } - - return result; - } - - @Override - public String encodeTime(String baseDN, Date date) { - PersistenceEntryManager persistenceEntryManager = getEntryManagerForDn(baseDN); - return persistenceEntryManager.encodeTime(baseDN, date); - } - - @Override - public List exportEntry(String dn) { - PersistenceEntryManager persistenceEntryManager = getEntryManagerForDn(dn); - return persistenceEntryManager.exportEntry(dn); - } - - @Override - public void importEntry(String dn, List data) { - throw new UnsupportedOperationException("Method not implemented."); - } - - @Override - public T find(Class entryClass, Object primaryKey) { - PersistenceEntryManager persistenceEntryManager = getEntryManagerForDn(primaryKey); - return persistenceEntryManager.find(entryClass, primaryKey); - } - - @Override - public T find(Object primaryKey, Class entryClass, String[] ldapReturnAttributes) { - PersistenceEntryManager persistenceEntryManager = getEntryManagerForDn(primaryKey); - return persistenceEntryManager.find(primaryKey, entryClass, ldapReturnAttributes); - } - - @Override - public List findEntries(Object entry) { - Class entryClass = entry.getClass(); - Object dnValue = getDNValue(entry, entryClass); - - PersistenceEntryManager persistenceEntryManager = getEntryManagerForDn(dnValue); - return persistenceEntryManager.findEntries(entry); - } - - @Override - public List findEntries(Object entry, int count) { - Class entryClass = entry.getClass(); - Object dnValue = getDNValue(entry, entryClass); - - PersistenceEntryManager persistenceEntryManager = getEntryManagerForDn(dnValue); - return persistenceEntryManager.findEntries(entry, count); - } - - @Override - public List findEntries(String baseDN, Class entryClass, Filter filter) { - PersistenceEntryManager persistenceEntryManager = getEntryManagerForDn(baseDN); - return persistenceEntryManager.findEntries(baseDN, entryClass, filter); - } - - @Override - public List findEntries(String baseDN, Class entryClass, Filter filter, int count) { - PersistenceEntryManager persistenceEntryManager = getEntryManagerForDn(baseDN); - return persistenceEntryManager.findEntries(baseDN, entryClass, filter, count); - } - - @Override - public List findEntries(String baseDN, Class entryClass, Filter filter, SearchScope scope, String[] ldapReturnAttributes, - BatchOperation batchOperation, int start, int count, int chunkSize) { - PersistenceEntryManager persistenceEntryManager = getEntryManagerForDn(baseDN); - return persistenceEntryManager.findEntries(baseDN, entryClass, filter, scope, ldapReturnAttributes, batchOperation, start, count, - chunkSize); - } - - @Override - public List findEntries(String baseDN, Class entryClass, Filter filter, SearchScope scope, String[] ldapReturnAttributes, - int start, int count, int chunkSize) { - PersistenceEntryManager persistenceEntryManager = getEntryManagerForDn(baseDN); - return persistenceEntryManager.findEntries(baseDN, entryClass, filter, scope, ldapReturnAttributes, start, count, chunkSize); - } - - @Override - public List findEntries(String baseDN, Class entryClass, Filter filter, String[] ldapReturnAttributes) { - PersistenceEntryManager persistenceEntryManager = getEntryManagerForDn(baseDN); - return persistenceEntryManager.findEntries(baseDN, entryClass, filter, ldapReturnAttributes); - } - - @Override - public List findEntries(String baseDN, Class entryClass, Filter filter, String[] ldapReturnAttributes, int count) { - PersistenceEntryManager persistenceEntryManager = getEntryManagerForDn(baseDN); - return persistenceEntryManager.findEntries(baseDN, entryClass, filter, ldapReturnAttributes, count); - } - - @Override - public PagedResult findPagedEntries(String baseDN, Class entryClass, Filter filter, String[] ldapReturnAttributes, String sortBy, - SortOrder sortOrder, int start, int count, int chunkSize) { - PersistenceEntryManager persistenceEntryManager = getEntryManagerForDn(baseDN); - return persistenceEntryManager.findPagedEntries(baseDN, entryClass, filter, ldapReturnAttributes, sortBy, - sortOrder, start, count, chunkSize); - } - - @Override - public boolean hasBranchesSupport(String dn) { - PersistenceEntryManager persistenceEntryManager = getEntryManagerForDn(dn); - return persistenceEntryManager.hasBranchesSupport(dn); - } - - @Override - public String getPersistenceType(String primaryKey) { - PersistenceEntryManager persistenceEntryManager = getEntryManagerForDn(primaryKey); - return persistenceEntryManager.getPersistenceType(primaryKey); - } - - private PersistenceEntryManager getPersistenceEntryManagerByKey(String key) { - if ("_".equals(key)) { - return defaultPersistenceEntryManager; - } - - String[] baseNameParts = key.split("_"); - if (ArrayHelper.isEmpty(baseNameParts)) { - throw new KeyConversionException("Failed to determine base key part!"); - } - - PersistenceEntryManager persistenceEntryManager = baseNameToEntryManagerMapping.get(baseNameParts[0]); - if (persistenceEntryManager != null) { - return persistenceEntryManager; - } - - return defaultPersistenceEntryManager; - } - - private PersistenceEntryManager getEntryManagerForDn(Object baseDn) { - if (StringHelper.isEmptyString(baseDn)) { - throw new MappingException("Entry DN is null"); - } - - return getEntryManagerForDn(baseDn.toString()); - } - - private PersistenceEntryManager getEntryManagerForDn(String baseDn) { - if (StringHelper.isEmpty(baseDn)) { - throw new MappingException("Entry DN is null"); - } - - ParsedKey parsedKey = KEY_CONVERTER.convertToKey(baseDn); - return getPersistenceEntryManagerByKey(parsedKey.getKey()); - } - - public HybridPersistenceOperationService getOperationService() { - return operationService; - } - - @Override - public T merge(T entry) { - Class entryClass = entry.getClass(); - Object dnValue = getDNValue(entry, entryClass); - - PersistenceEntryManager persistenceEntryManager = getEntryManagerForDn(dnValue); - return persistenceEntryManager.merge(entry); - } - - @Override - public void persist(Object entry) { - Class entryClass = entry.getClass(); - Object dnValue = getDNValue(entry, entryClass); - - PersistenceEntryManager persistenceEntryManager = getEntryManagerForDn(dnValue); - persistenceEntryManager.persist(entry); - } - - @Override - public void remove(Object entry) { - Class entryClass = entry.getClass(); - Object dnValue = getDNValue(entry, entryClass); - - PersistenceEntryManager persistenceEntryManager = getEntryManagerForDn(dnValue); - persistenceEntryManager.remove(entry); - } - - @Override - public void remove(String primaryKey) { - PersistenceEntryManager persistenceEntryManager = getEntryManagerForDn(primaryKey); - persistenceEntryManager.remove(primaryKey); - } - - @Override - public int remove(String primaryKey, Class entryClass, Filter filter, int count) { - PersistenceEntryManager persistenceEntryManager = getEntryManagerForDn(primaryKey); - return persistenceEntryManager.remove(primaryKey, entryClass, filter, count); - } - - @Override - public void removeDeleteSubscriber(DeleteNotifier subscriber) { - if (this.persistenceEntryManagers == null) { - return; - } - - for (PersistenceEntryManager persistenceEntryManager : persistenceEntryManagers.values()) { - persistenceEntryManager.removeDeleteSubscriber(subscriber); - } - } - - @Override - public void removeRecursively(String dn) { - PersistenceEntryManager persistenceEntryManager = getEntryManagerForDn(dn); - persistenceEntryManager.removeRecursively(dn); - } - - //************************************************************************* - // Internal methods which not needed in Hybrid Entry Manager - //************************************************************************* - - @Override - protected void persist(String dn, List attributes) { - throw new UnsupportedOperationException("Method not implemented."); - } - - @Override - protected void merge(String dn, List attributeDataModifications) { - throw new UnsupportedOperationException("Method not implemented."); - } - - @Override - protected List find(String dn, Map propertiesAnnotationsMap, String... ldapReturnAttributes) { - throw new UnsupportedOperationException("Method not implemented."); - } - - @Override - protected boolean contains(String baseDN, Class entryClass, List propertiesAnnotations, Filter filter, String[] objectClasses, String[] ldapReturnAttributes) { - throw new UnsupportedOperationException("Method not implemented."); - } - - @Override - protected Date decodeTime(String date) { - throw new UnsupportedOperationException("Method not implemented."); - } - - @Override - protected String encodeTime(Date date) { - throw new UnsupportedOperationException("Method not implemented."); - } - - @Override - protected void updateMergeChanges(String baseDn, T entry, boolean isSchemaUpdate, Class entryClass, - Map attributesFromLdapMap, List attributeDataModifications) { - throw new UnsupportedOperationException("Method not implemented."); - } - -} diff --git a/persistence-hybrid/src/main/java/org/gluu/persist/hybrid/impl/HybridEntryManagerFactory.java b/persistence-hybrid/src/main/java/org/gluu/persist/hybrid/impl/HybridEntryManagerFactory.java deleted file mode 100644 index 21ea8d07f..000000000 --- a/persistence-hybrid/src/main/java/org/gluu/persist/hybrid/impl/HybridEntryManagerFactory.java +++ /dev/null @@ -1,141 +0,0 @@ -package org.gluu.persist.hybrid.impl; - -import java.io.File; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; - -import javax.enterprise.context.ApplicationScoped; -import javax.inject.Inject; - -import org.gluu.persist.PersistenceEntryManager; -import org.gluu.persist.PersistenceEntryManagerFactory; -import org.gluu.persist.exception.operation.ConfigurationException; -import org.gluu.persist.operation.PersistenceOperationService; -import org.gluu.persist.service.BaseFactoryService; -import org.gluu.util.PropertiesHelper; -import org.gluu.util.StringHelper; -import org.gluu.util.properties.FileConfiguration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Hybrid Entry Manager Factory - * - * @author Yuriy Movchan Date: 05/13/2018 - */ -@ApplicationScoped -public class HybridEntryManagerFactory implements PersistenceEntryManagerFactory { - static { - if (System.getProperty("gluu.base") != null) { - BASE_DIR = System.getProperty("gluu.base"); - } else if ((System.getProperty("catalina.base") != null) && (System.getProperty("catalina.base.ignore") == null)) { - BASE_DIR = System.getProperty("catalina.base"); - } else if (System.getProperty("catalina.home") != null) { - BASE_DIR = System.getProperty("catalina.home"); - } else if (System.getProperty("jboss.home.dir") != null) { - BASE_DIR = System.getProperty("jboss.home.dir"); - } else { - BASE_DIR = null; - } - } - - public static final String BASE_DIR; - public static final String DIR = BASE_DIR + File.separator + "conf" + File.separator; - - public static final String PERSISTANCE_TYPE = "hybrid"; - public static final String PROPERTIES_FILE = "gluu-hybrid.properties"; - - private static final Logger LOG = LoggerFactory.getLogger(HybridEntryManagerFactory.class); - - @Inject - private BaseFactoryService persistanceFactoryService; - - private String[] persistenceTypes; - - private Properties hybridMappingProperties; - - @Override - public String getPersistenceType() { - return PERSISTANCE_TYPE; - } - - @Override - public HashMap getConfigurationFileNames() { - HashMap confs = new HashMap(); - confs.put(PERSISTANCE_TYPE, PROPERTIES_FILE); - - HashMap allConfs = getAllConfigurationFileNames(PROPERTIES_FILE); - confs.putAll(allConfs); - - return confs; - } - - private HashMap getAllConfigurationFileNames(String confFileName) { - HashMap allConfs = new HashMap(); - - FileConfiguration fileConf = new FileConfiguration(DIR + confFileName); - if (!fileConf.isLoaded()) { - LOG.error("Unable to load configuration file '{}'", DIR + confFileName); - throw new ConfigurationException(String.format("Unable to load configuration file: '%s'", fileConf)); - } - - String storagesList = fileConf.getString("storages", null); - if (StringHelper.isEmpty(storagesList)) { - throw new ConfigurationException("'storages' key not exists or value is empty!"); - } - - this.persistenceTypes = StringHelper.split(storagesList, ","); - for (String persistenceType : persistenceTypes) { - PersistenceEntryManagerFactory persistenceEntryManagerFactory = persistanceFactoryService.getPersistenceEntryManagerFactory(persistenceType); - if (persistenceEntryManagerFactory == null) { - throw new ConfigurationException(String.format("Unable to get Persistence Entry Manager Factory by type '%s'", persistenceType)); - } - - Map confs = persistenceEntryManagerFactory.getConfigurationFileNames(); - allConfs.putAll(confs); - } - - return allConfs; - } - - @Override - public HybridEntryManager createEntryManager(Properties conf) { - HashMap сonnectionProperties = new HashMap(); - - HashMap persistenceEntryManagers = new HashMap(); - List operationServices = new ArrayList(); - - for (String persistenceType : persistenceTypes) { - PersistenceEntryManagerFactory persistenceEntryManagerFactory = persistanceFactoryService.getPersistenceEntryManagerFactory(persistenceType); - if (persistenceEntryManagerFactory == null) { - throw new ConfigurationException(String.format("Unable to get Persistence Entry Manager Factory by type '%s'", persistenceType)); - } - - Properties entryManagerConf = PropertiesHelper.findProperties(conf, persistenceType); - PersistenceEntryManager persistenceEntryManager = persistenceEntryManagerFactory.createEntryManager(entryManagerConf); - - persistenceEntryManagers.put(persistenceType, persistenceEntryManager); - operationServices.add(persistenceEntryManager.getOperationService()); - - сonnectionProperties.put(persistenceType, entryManagerConf); - } - - this.hybridMappingProperties = PropertiesHelper.filterProperties(conf, PERSISTANCE_TYPE); - - HybridPersistenceOperationService hybridOperationService = new HybridPersistenceOperationService(operationServices); - - HybridEntryManager hybridEntryManager = new HybridEntryManager(hybridMappingProperties, persistenceEntryManagers, hybridOperationService); - LOG.info("Created HybridEntryManager: {}", hybridOperationService); - - return hybridEntryManager; - } - - @Override - public void initStandalone(BaseFactoryService persistanceFactoryService) { - this.persistanceFactoryService = persistanceFactoryService; - } - -} diff --git a/persistence-hybrid/src/main/java/org/gluu/persist/hybrid/impl/HybridPersistenceOperationService.java b/persistence-hybrid/src/main/java/org/gluu/persist/hybrid/impl/HybridPersistenceOperationService.java deleted file mode 100644 index 41e4d3a6a..000000000 --- a/persistence-hybrid/src/main/java/org/gluu/persist/hybrid/impl/HybridPersistenceOperationService.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.gluu.persist.hybrid.impl; - -import java.util.List; - -import org.gluu.persist.operation.PersistenceOperationService; - -/** - * Hybrid Operation Service - * - * @author Yuriy Movchan Date: 05/13/2018 - */ -public class HybridPersistenceOperationService implements PersistenceOperationService { - - private List persistenceOperationServices; - - public HybridPersistenceOperationService(List persistenceOperationServices) { - this.persistenceOperationServices = persistenceOperationServices; - } - - @Override - public boolean isConnected() { - for(PersistenceOperationService persistenceOperationService : persistenceOperationServices) { - if (!persistenceOperationService.isConnected()) { - return false; - } - } - - return true; - } - -} diff --git a/persistence-ldap-sample/pom.xml b/persistence-ldap-sample/pom.xml deleted file mode 100644 index 0f120d571..000000000 --- a/persistence-ldap-sample/pom.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - 4.0.0 - org.gluu - oxcore-persistence-ldap-sample - persistence-ldapSample - Sample project to show persistence-ldap functionality - - - org.gluu - oxcore - 4.0.0-SNAPSHOT - - - - ${maven.min-version} - - - - - org.gluu - oxcore-persistence-ldap - ${project.version} - - - org.gluu - oxcore-persistence-annotation - ${project.version} - - - - \ No newline at end of file diff --git a/persistence-ldap-sample/src/main/java/org/gluu/ldap/LdapSample.java b/persistence-ldap-sample/src/main/java/org/gluu/ldap/LdapSample.java deleted file mode 100644 index 27c2d7d03..000000000 --- a/persistence-ldap-sample/src/main/java/org/gluu/ldap/LdapSample.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.gluu.ldap; - -import java.util.List; - -import org.apache.log4j.Logger; -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.status.StatusLogger; -import org.gluu.ldap.model.SimpleAttribute; -import org.gluu.ldap.model.SimpleGrant; -import org.gluu.ldap.model.SimpleSession; -import org.gluu.ldap.model.SimpleUser; -import org.gluu.log.LoggingHelper; -import org.gluu.persist.ldap.impl.LdapEntryManager; -import org.gluu.persist.model.PagedResult; -import org.gluu.persist.model.SearchScope; -import org.gluu.persist.model.SortOrder; -import org.gluu.persist.model.base.CustomAttribute; -import org.gluu.search.filter.Filter; - -/** - * @author Yuriy Movchan Date: 11/03/2016 - */ -public final class LdapSample { - - private static final Logger LOG; - - static { - StatusLogger.getLogger().setLevel(Level.OFF); - LoggingHelper.configureConsoleAppender(); - LOG = Logger.getLogger(LdapSample.class); - } - - private LdapSample() { - } - - public static void main(String[] args) { - // Prepare sample connection details - LdapSampleEntryManager ldapSampleEntryManager = new LdapSampleEntryManager(); - - // Create LDAP entry manager - LdapEntryManager ldapEntryManager = ldapSampleEntryManager.createLdapEntryManager(); - - // Find all users which have specified object classes defined in SimpleUser - List users = ldapEntryManager.findEntries("o=gluu", SimpleUser.class, null); - for (SimpleUser user : users) { - LOG.debug("User with uid: " + user.getUserId()); - } - - if (users.size() > 0) { - // Add attribute "streetAddress" to first user - SimpleUser user = users.get(0); - user.getCustomAttributes().add(new CustomAttribute("streetAddress", "Somewhere: " + System.currentTimeMillis())); - - ldapEntryManager.merge(user); - } - - Filter filter = Filter.createEqualityFilter("gluuStatus", "active"); - List attributes = ldapEntryManager.findEntries("o=gluu", SimpleAttribute.class, filter, SearchScope.SUB, null, null, 10, 0, - 0); - for (SimpleAttribute attribute : attributes) { - LOG.debug("Attribute with displayName: " + attribute.getCustomAttributes().get(1)); - } - - List sessions = ldapEntryManager.findEntries("o=gluu", SimpleSession.class, filter, SearchScope.SUB, null, null, 10, 0, 0); - LOG.debug("Found sessions: " + sessions.size()); - - List grants = ldapEntryManager.findEntries("o=gluu", SimpleGrant.class, null, SearchScope.SUB, new String[] { "grtId" }, - null, 10, 0, 0); - LOG.debug("Found grants: " + grants.size()); - - try { - PagedResult vlvResponse = ldapEntryManager.findPagedEntries("o=gluu", SimpleUser.class, null, - new String[] { "uid", "displayName", "gluuStatus" }, "displayName", SortOrder.ASCENDING, 10, 100000, 1000); - - LOG.debug("Found persons: " + vlvResponse.getTotalEntriesCount()); - System.out.println(vlvResponse.getEntries().size()); - } catch (Exception ex) { - LOG.error("Failed to search", ex); - } - } - -} diff --git a/persistence-ldap-sample/src/main/java/org/gluu/ldap/LdapSampleBatchJob.java b/persistence-ldap-sample/src/main/java/org/gluu/ldap/LdapSampleBatchJob.java deleted file mode 100644 index 73c9ae8ef..000000000 --- a/persistence-ldap-sample/src/main/java/org/gluu/ldap/LdapSampleBatchJob.java +++ /dev/null @@ -1,153 +0,0 @@ -package org.gluu.ldap; - -import java.text.ParseException; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Date; -import java.util.List; - -import org.apache.log4j.Logger; -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.status.StatusLogger; -import org.gluu.ldap.model.SimpleClient; -import org.gluu.ldap.model.SimpleSession; -import org.gluu.ldap.model.SimpleTokenLdap; -import org.gluu.log.LoggingHelper; -import org.gluu.persist.exception.EntryPersistenceException; -import org.gluu.persist.ldap.impl.LdapEntryManager; -import org.gluu.persist.model.BatchOperation; -import org.gluu.persist.model.DefaultBatchOperation; -import org.gluu.persist.model.ProcessBatchOperation; -import org.gluu.persist.model.SearchScope; -import org.gluu.persist.model.base.CustomAttribute; -import org.gluu.search.filter.Filter; - -import com.unboundid.util.StaticUtils; - -/** - * Created by eugeniuparvan on 1/12/17. - */ -public final class LdapSampleBatchJob { - private static final Logger LOG; - - static { - StatusLogger.getLogger().setLevel(Level.OFF); - LoggingHelper.configureConsoleAppender(); - LOG = Logger.getLogger(LdapSample.class); - } - - private LdapSampleBatchJob() { } - - public static void main(String[] args) { - // Prepare sample connection details - LdapSampleEntryManager ldapSampleEntryManager = new LdapSampleEntryManager(); - - // Create LDAP entry manager - final LdapEntryManager ldapEntryManager = ldapSampleEntryManager.createLdapEntryManager(); - - BatchOperation tokenLdapBatchOperation = new ProcessBatchOperation() { - private int processedCount = 0; - - @Override - public void performAction(List objects) { - for (SimpleTokenLdap simpleTokenLdap : objects) { - try { - CustomAttribute customAttribute = getUpdatedAttribute(ldapEntryManager, simpleTokenLdap.getDn(), "oxAuthExpiration", - simpleTokenLdap.getAttribute("oxAuthExpiration")); - simpleTokenLdap.setCustomAttributes(Arrays.asList(new CustomAttribute[] {customAttribute})); - ldapEntryManager.merge(simpleTokenLdap); - processedCount++; - } catch (EntryPersistenceException ex) { - LOG.error("Failed to update entry", ex); - } - } - - LOG.info("Total processed: " + processedCount); - } - }; - - final Filter filter1 = Filter.createPresenceFilter("oxAuthExpiration"); - ldapEntryManager.findEntries("o=gluu", SimpleTokenLdap.class, filter1, SearchScope.SUB, new String[] {"oxAuthExpiration"}, - tokenLdapBatchOperation, 0, 0, 100); - - BatchOperation sessionBatchOperation = new ProcessBatchOperation() { - private int processedCount = 0; - - @Override - public void performAction(List objects) { - for (SimpleSession simpleSession : objects) { - try { - CustomAttribute customAttribute = getUpdatedAttribute(ldapEntryManager, simpleSession.getDn(), "oxLastAccessTime", - simpleSession.getAttribute("oxLastAccessTime")); - simpleSession.setCustomAttributes(Arrays.asList(new CustomAttribute[] {customAttribute})); - ldapEntryManager.merge(simpleSession); - processedCount++; - } catch (EntryPersistenceException ex) { - LOG.error("Failed to update entry", ex); - } - } - - LOG.info("Total processed: " + processedCount); - } - }; - - final Filter filter2 = Filter.createPresenceFilter("oxLastAccessTime"); - ldapEntryManager.findEntries("o=gluu", SimpleSession.class, filter2, SearchScope.SUB, new String[] {"oxLastAccessTime"}, - sessionBatchOperation, 0, 0, 100); - - BatchOperation clientBatchOperation = new ProcessBatchOperation() { - private int processedCount = 0; - - @Override - public void performAction(List objects) { - for (SimpleClient simpleClient : objects) { - processedCount++; - } - - LOG.info("Total processed: " + processedCount); - } - }; - - final Filter filter3 = Filter.createPresenceFilter("oxAuthClientSecretExpiresAt"); - List result3 = ldapEntryManager.findEntries("o=gluu", SimpleClient.class, filter3, SearchScope.SUB, - new String[] {"oxAuthClientSecretExpiresAt"}, clientBatchOperation, 0, 0, 1000); - - LOG.info("Result count (without collecting results): " + result3.size()); - - BatchOperation clientBatchOperation2 = new DefaultBatchOperation() { - private int processedCount = 0; - - @Override - public void performAction(List objects) { - for (SimpleClient simpleClient : objects) { - processedCount++; - } - - LOG.info("Total processed: " + processedCount); - } - }; - - final Filter filter4 = Filter.createPresenceFilter("oxAuthClientSecretExpiresAt"); - List result4 = ldapEntryManager.findEntries("o=gluu", SimpleClient.class, filter4, SearchScope.SUB, - new String[] {"oxAuthClientSecretExpiresAt"}, clientBatchOperation2, 0, 0, 1000); - - LOG.info("Result count (with collecting results): " + result4.size()); - } - - private static CustomAttribute getUpdatedAttribute(LdapEntryManager ldapEntryManager, String baseDn, String attributeName, String attributeValue) { - try { - Calendar calendar = Calendar.getInstance(); - Date oxLastAccessTimeDate = StaticUtils.decodeGeneralizedTime(attributeValue); - calendar.setTime(oxLastAccessTimeDate); - calendar.add(Calendar.SECOND, -1); - - CustomAttribute customAttribute = new CustomAttribute(); - customAttribute.setName(attributeName); - customAttribute.setValue(ldapEntryManager.encodeTime(baseDn, calendar.getTime())); - return customAttribute; - } catch (ParseException e) { - LOG.error("Can't parse attribute", e); - } - return null; - } -} diff --git a/persistence-ldap-sample/src/main/java/org/gluu/ldap/LdapSampleDelete.java b/persistence-ldap-sample/src/main/java/org/gluu/ldap/LdapSampleDelete.java deleted file mode 100644 index 4e9f91cd0..000000000 --- a/persistence-ldap-sample/src/main/java/org/gluu/ldap/LdapSampleDelete.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.gluu.ldap; - -import java.util.Date; -import java.util.List; - -import org.apache.log4j.Logger; -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.status.StatusLogger; -import org.gluu.ldap.model.SimpleAttribute; -import org.gluu.ldap.model.SimpleGrant; -import org.gluu.ldap.model.SimpleSession; -import org.gluu.ldap.model.SimpleUser; -import org.gluu.log.LoggingHelper; -import org.gluu.persist.ldap.impl.LdapEntryManager; -import org.gluu.persist.model.PagedResult; -import org.gluu.persist.model.SearchScope; -import org.gluu.persist.model.SortOrder; -import org.gluu.persist.model.base.CustomAttribute; -import org.gluu.persist.model.base.DeletableEntity; -import org.gluu.search.filter.Filter; - -/** - * @author Yuriy Movchan Date: 11/03/2016 - */ -public final class LdapSampleDelete { - - private static final Logger LOG; - - static { - StatusLogger.getLogger().setLevel(Level.OFF); - LoggingHelper.configureConsoleAppender(); - LOG = Logger.getLogger(LdapSampleDelete.class); - } - - private LdapSampleDelete() { - } - - public static void main(String[] args) { - // Prepare sample connection details - LdapSampleEntryManager ldapSampleEntryManager = new LdapSampleEntryManager(); - - // Create LDAP entry manager - LdapEntryManager ldapEntryManager = ldapSampleEntryManager.createLdapEntryManager(); - - String baseDn = "ou=cache,o=gluu"; - Filter filter = Filter.createANDFilter( - Filter.createEqualityFilter("del", true), - Filter.createLessOrEqualFilter("oxAuthExpiration", ldapEntryManager.encodeTime(baseDn, new Date(System.currentTimeMillis() + 2 * 24 * 60 * 60 * 1000))) - ); - - int result = ldapEntryManager.remove(baseDn, DeletableEntity.class, filter, 100); - System.out.println(result); - } - -} diff --git a/persistence-ldap-sample/src/main/java/org/gluu/ldap/LdapSampleEntryManager.java b/persistence-ldap-sample/src/main/java/org/gluu/ldap/LdapSampleEntryManager.java deleted file mode 100644 index 3f65fd8c1..000000000 --- a/persistence-ldap-sample/src/main/java/org/gluu/ldap/LdapSampleEntryManager.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.gluu.ldap; - -import java.util.Properties; - -import org.apache.log4j.Logger; -import org.gluu.persist.ldap.impl.LdapEntryManager; -import org.gluu.persist.ldap.impl.LdapEntryManagerFactory; - -/** - * @author Yuriy Movchan - * Date: 01/13/2017 - */ -public class LdapSampleEntryManager { - - private static final Logger LOG = Logger.getLogger(LdapSampleEntryManager.class); - - private Properties getSampleConnectionProperties() { - Properties connectionProperties = new Properties(); - - connectionProperties.put("ldap.bindDN", "cn=Directory Manager"); - connectionProperties.put("ldap.bindPassword", "test"); - connectionProperties.put("ldap.servers", "localhost:1636"); - connectionProperties.put("ldap.useSSL", "true"); - connectionProperties.put("ldap.maxconnections", "3"); - - return connectionProperties; - } - - public LdapEntryManager createLdapEntryManager() { - LdapEntryManagerFactory ldapEntryManagerFactory = new LdapEntryManagerFactory(); - Properties connectionProperties = getSampleConnectionProperties(); - - LdapEntryManager ldapEntryManager = ldapEntryManagerFactory.createEntryManager(connectionProperties); - LOG.debug("Created LdapEntryManager: " + ldapEntryManager); - - return ldapEntryManager; - } - -} diff --git a/persistence-ldap-sample/src/main/java/org/gluu/ldap/LdapSampleSimpleSessionSample.java b/persistence-ldap-sample/src/main/java/org/gluu/ldap/LdapSampleSimpleSessionSample.java deleted file mode 100644 index 920b9797c..000000000 --- a/persistence-ldap-sample/src/main/java/org/gluu/ldap/LdapSampleSimpleSessionSample.java +++ /dev/null @@ -1,93 +0,0 @@ -package org.gluu.ldap; - -import java.util.Date; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ThreadFactory; - -import org.apache.log4j.Logger; -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.status.StatusLogger; -import org.gluu.ldap.model.SimpleSessionState; -import org.gluu.log.LoggingHelper; -import org.gluu.persist.ldap.impl.LdapEntryManager; - -/** - * @author Yuriy Movchan Date: 01/25/2016 - */ -public final class LdapSampleSimpleSessionSample { - - private static final Logger LOG; - - static { - StatusLogger.getLogger().setLevel(Level.OFF); - LoggingHelper.configureConsoleAppender(); - LOG = Logger.getLogger(LdapSampleSimpleSessionSample.class); - } - - private LdapSampleSimpleSessionSample() { - } - - public static void main(String[] args) throws InterruptedException { - // Prepare sample connection details - LdapSampleEntryManager ldapSampleEntryManager = new LdapSampleEntryManager(); - final LdapEntryManager ldapEntryManager = ldapSampleEntryManager.createLdapEntryManager(); - - try { - - // Create LDAP entry manager - String sessionId = "xyzcyzxy-a41a-45ad-8a83-61485dbad561"; - final String sessionDn = "uniqueIdentifier=" + sessionId + ",ou=session,o=gluu"; - final String userDn = - "inum=@!E8F2.853B.1E7B.ACE2!0001!39A4.C163!0000!A8F2.DE1E.D7FB,ou=people,o=gluu"; - - final SimpleSessionState simpleSessionState = new SimpleSessionState(); - simpleSessionState.setDn(sessionDn); - simpleSessionState.setId(sessionId); - simpleSessionState.setLastUsedAt(new Date()); - - ldapEntryManager.persist(simpleSessionState); - System.out.println("Persisted"); - - int threadCount = 500; - ExecutorService executorService = Executors.newFixedThreadPool(threadCount, daemonThreadFactory()); - for (int i = 0; i < threadCount; i++) { - final int count = i; - executorService.execute(new Runnable() { - @Override - public void run() { - final SimpleSessionState simpleSessionStateFromLdap = ldapEntryManager.find(SimpleSessionState.class, sessionDn); - String beforeUserDn = simpleSessionStateFromLdap.getUserDn(); - String randomUserDn = count % 2 == 0 ? userDn : ""; - - try { - simpleSessionStateFromLdap.setUserDn(randomUserDn); - simpleSessionStateFromLdap.setLastUsedAt(new Date()); - ldapEntryManager.merge(simpleSessionStateFromLdap); - System.out.println("Merged thread: " + count + ", userDn: " + randomUserDn + ", before userDn: " + beforeUserDn); - } catch (Throwable e) { - System.out.println("ERROR !!!, thread: " + count + ", userDn: " + randomUserDn + ", before userDn: " + beforeUserDn - + ", error:" + e.getMessage()); - // e.printStackTrace(); - } - } - }); - } - - Thread.sleep(5000L); - } finally { - ldapEntryManager.getOperationService().getConnectionPool().close(); - } - } - - public static ThreadFactory daemonThreadFactory() { - return new ThreadFactory() { - public Thread newThread(Runnable runnable) { - Thread thread = new Thread(runnable); - thread.setDaemon(true); - return thread; - } - }; - } - -} diff --git a/persistence-ldap-sample/src/main/java/org/gluu/ldap/model/SimpleAttribute.java b/persistence-ldap-sample/src/main/java/org/gluu/ldap/model/SimpleAttribute.java deleted file mode 100644 index 6f3ee866c..000000000 --- a/persistence-ldap-sample/src/main/java/org/gluu/ldap/model/SimpleAttribute.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.ldap.model; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -import org.gluu.persist.model.base.CustomAttribute; -import org.gluu.persist.annotation.AttributesList; -import org.gluu.persist.annotation.CustomObjectClass; -import org.gluu.persist.annotation.DN; -import org.gluu.persist.annotation.DataEntry; -import org.gluu.persist.annotation.ObjectClass; -import org.gluu.util.StringHelper; - -/** - * @author Yuriy Movchan - * Date: 12/30/2016 - */ -@DataEntry -@ObjectClass(value = "gluuAttribute") -public class SimpleAttribute implements Serializable { - - private static final long serialVersionUID = -1634191420188575733L; - - @DN - private String dn; - - @AttributesList(name = "name", value = "values", sortByName = true) - private List customAttributes = new ArrayList(); - - @CustomObjectClass - private String[] customObjectClasses; - - public String getDn() { - return dn; - } - - public void setDn(String dn) { - this.dn = dn; - } - - public List getCustomAttributes() { - return customAttributes; - } - - public void setCustomAttributes(List customAttributes) { - this.customAttributes = customAttributes; - } - - public String getAttribute(String ldapAttribute) { - String attribute = null; - if (ldapAttribute != null && !ldapAttribute.isEmpty()) { - for (CustomAttribute customAttribute : customAttributes) { - if (customAttribute.getName().equals(ldapAttribute)) { - attribute = customAttribute.getValue(); - break; - } - } - } - - return attribute; - } - - public List getAttributeValues(String ldapAttribute) { - List values = null; - if (ldapAttribute != null && !ldapAttribute.isEmpty()) { - for (CustomAttribute customAttribute : customAttributes) { - if (StringHelper.equalsIgnoreCase(customAttribute.getName(), ldapAttribute)) { - values = customAttribute.getValues(); - break; - } - } - } - - return values; - } - - public String[] getCustomObjectClasses() { - return customObjectClasses; - } - - public void setCustomObjectClasses(String[] customObjectClasses) { - this.customObjectClasses = customObjectClasses; - } - -} diff --git a/persistence-ldap-sample/src/main/java/org/gluu/ldap/model/SimpleClient.java b/persistence-ldap-sample/src/main/java/org/gluu/ldap/model/SimpleClient.java deleted file mode 100644 index f3418c6c1..000000000 --- a/persistence-ldap-sample/src/main/java/org/gluu/ldap/model/SimpleClient.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.ldap.model; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -import org.gluu.persist.model.base.CustomAttribute; -import org.gluu.persist.annotation.AttributesList; -import org.gluu.persist.annotation.CustomObjectClass; -import org.gluu.persist.annotation.DN; -import org.gluu.persist.annotation.DataEntry; -import org.gluu.persist.annotation.ObjectClass; -import org.gluu.util.StringHelper; - -/** - * @author Yuriy Movchan - * Date: 02/08/2018 - */ -@DataEntry -@ObjectClass(value = "oxAuthClient") -public class SimpleClient implements Serializable { - - private static final long serialVersionUID = -2534191420188575733L; - - @DN - private String dn; - - @AttributesList(name = "name", value = "values", sortByName = true) - private List customAttributes = new ArrayList(); - - @CustomObjectClass - private String[] customObjectClasses; - - public String getDn() { - return dn; - } - - public void setDn(String dn) { - this.dn = dn; - } - - public List getCustomAttributes() { - return customAttributes; - } - - public void setCustomAttributes(List customAttributes) { - this.customAttributes = customAttributes; - } - - public String getAttribute(String ldapAttribute) { - String attribute = null; - if (ldapAttribute != null && !ldapAttribute.isEmpty()) { - for (CustomAttribute customAttribute : customAttributes) { - if (customAttribute.getName().equals(ldapAttribute)) { - attribute = customAttribute.getValue(); - break; - } - } - } - - return attribute; - } - - public List getAttributeValues(String ldapAttribute) { - List values = null; - if (ldapAttribute != null && !ldapAttribute.isEmpty()) { - for (CustomAttribute customAttribute : customAttributes) { - if (StringHelper.equalsIgnoreCase(customAttribute.getName(), ldapAttribute)) { - values = customAttribute.getValues(); - break; - } - } - } - - return values; - } - - public String[] getCustomObjectClasses() { - return customObjectClasses; - } - - public void setCustomObjectClasses(String[] customObjectClasses) { - this.customObjectClasses = customObjectClasses; - } - -} diff --git a/persistence-ldap-sample/src/main/java/org/gluu/ldap/model/SimpleGrant.java b/persistence-ldap-sample/src/main/java/org/gluu/ldap/model/SimpleGrant.java deleted file mode 100644 index 1ef8638c1..000000000 --- a/persistence-ldap-sample/src/main/java/org/gluu/ldap/model/SimpleGrant.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.ldap.model; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -import org.gluu.persist.model.base.CustomAttribute; -import org.gluu.persist.annotation.AttributesList; -import org.gluu.persist.annotation.CustomObjectClass; -import org.gluu.persist.annotation.DN; -import org.gluu.persist.annotation.DataEntry; -import org.gluu.persist.annotation.ObjectClass; -import org.gluu.util.StringHelper; - -/** - * @author Yuriy Movchan - * Date: 12/30/2016 - */ -@DataEntry -@ObjectClass(value = "oxAuthGrant") -public class SimpleGrant implements Serializable { - - private static final long serialVersionUID = -1234191420188575733L; - - @DN - private String dn; - - @AttributesList(name = "name", value = "values", sortByName = true) - private List customAttributes = new ArrayList(); - - @CustomObjectClass - private String[] customObjectClasses; - - public String getDn() { - return dn; - } - - public void setDn(String dn) { - this.dn = dn; - } - - public List getCustomAttributes() { - return customAttributes; - } - - public void setCustomAttributes(List customAttributes) { - this.customAttributes = customAttributes; - } - - public String getAttribute(String ldapAttribute) { - String attribute = null; - if (ldapAttribute != null && !ldapAttribute.isEmpty()) { - for (CustomAttribute customAttribute : customAttributes) { - if (customAttribute.getName().equals(ldapAttribute)) { - attribute = customAttribute.getValue(); - break; - } - } - } - - return attribute; - } - - public List getAttributeValues(String ldapAttribute) { - List values = null; - if (ldapAttribute != null && !ldapAttribute.isEmpty()) { - for (CustomAttribute customAttribute : customAttributes) { - if (StringHelper.equalsIgnoreCase(customAttribute.getName(), ldapAttribute)) { - values = customAttribute.getValues(); - break; - } - } - } - - return values; - } - - public String[] getCustomObjectClasses() { - return customObjectClasses; - } - - public void setCustomObjectClasses(String[] customObjectClasses) { - this.customObjectClasses = customObjectClasses; - } - -} diff --git a/persistence-ldap-sample/src/main/java/org/gluu/ldap/model/SimpleSession.java b/persistence-ldap-sample/src/main/java/org/gluu/ldap/model/SimpleSession.java deleted file mode 100644 index 53b33daf5..000000000 --- a/persistence-ldap-sample/src/main/java/org/gluu/ldap/model/SimpleSession.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.ldap.model; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -import org.gluu.persist.model.base.CustomAttribute; -import org.gluu.persist.annotation.AttributesList; -import org.gluu.persist.annotation.CustomObjectClass; -import org.gluu.persist.annotation.DN; -import org.gluu.persist.annotation.DataEntry; -import org.gluu.persist.annotation.ObjectClass; -import org.gluu.util.StringHelper; - -/** - * @author Yuriy Movchan - * Date: 12/30/2016 - */ -@DataEntry -@ObjectClass(value = "oxAuthSessionId") -public class SimpleSession implements Serializable { - - private static final long serialVersionUID = -1534191420188575733L; - - @DN - private String dn; - - @AttributesList(name = "name", value = "values", sortByName = true) - private List customAttributes = new ArrayList(); - - @CustomObjectClass - private String[] customObjectClasses; - - public String getDn() { - return dn; - } - - public void setDn(String dn) { - this.dn = dn; - } - - public List getCustomAttributes() { - return customAttributes; - } - - public void setCustomAttributes(List customAttributes) { - this.customAttributes = customAttributes; - } - - public String getAttribute(String ldapAttribute) { - String attribute = null; - if (ldapAttribute != null && !ldapAttribute.isEmpty()) { - for (CustomAttribute customAttribute : customAttributes) { - if (customAttribute.getName().equals(ldapAttribute)) { - attribute = customAttribute.getValue(); - break; - } - } - } - - return attribute; - } - - public List getAttributeValues(String ldapAttribute) { - List values = null; - if (ldapAttribute != null && !ldapAttribute.isEmpty()) { - for (CustomAttribute customAttribute : customAttributes) { - if (StringHelper.equalsIgnoreCase(customAttribute.getName(), ldapAttribute)) { - values = customAttribute.getValues(); - break; - } - } - } - - return values; - } - - public String[] getCustomObjectClasses() { - return customObjectClasses; - } - - public void setCustomObjectClasses(String[] customObjectClasses) { - this.customObjectClasses = customObjectClasses; - } - -} diff --git a/persistence-ldap-sample/src/main/java/org/gluu/ldap/model/SimpleSessionState.java b/persistence-ldap-sample/src/main/java/org/gluu/ldap/model/SimpleSessionState.java deleted file mode 100644 index 9f03df618..000000000 --- a/persistence-ldap-sample/src/main/java/org/gluu/ldap/model/SimpleSessionState.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.ldap.model; - -import java.io.Serializable; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -import javax.persistence.Transient; - -import org.gluu.persist.annotation.AttributeName; -import org.gluu.persist.annotation.DN; -import org.gluu.persist.annotation.DataEntry; -import org.gluu.persist.annotation.JsonObject; -import org.gluu.persist.annotation.ObjectClass; - -/** - * @author Yuriy Zabrovarnyy - * @author Javier Rojas Blum - * @version December 15, 2015 - */ -@DataEntry -@ObjectClass(value = "oxAuthSessionId") -public class SimpleSessionState implements Serializable { - - private static final long serialVersionUID = -237476411915686378L; - - @DN - private String dn; - - @AttributeName(name = "uniqueIdentifier") - private String id; - - @AttributeName(name = "oxLastAccessTime") - private Date lastUsedAt; - - @AttributeName(name = "oxAuthUserDN") - private String userDn; - - @AttributeName(name = "authnTime") - private Date authenticationTime; - - @AttributeName(name = "oxAuthSessionState") - private Boolean permissionGranted; - - @AttributeName(name = "oxAsJwt") - private Boolean isJwt = false; - - @AttributeName(name = "oxJwt") - private String jwt; - - @JsonObject - @AttributeName(name = "oxAuthSessionAttribute") - private Map sessionAttributes; - - @Transient - private transient boolean persisted; - - public String getDn() { - return dn; - } - - public void setDn(String dn) { - this.dn = dn; - } - - public String getJwt() { - return jwt; - } - - public void setJwt(String jwt) { - this.jwt = jwt; - } - - public Boolean getIsJwt() { - return isJwt; - } - - public void setIsJwt(Boolean isJwt) { - this.isJwt = isJwt; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public Date getLastUsedAt() { - return lastUsedAt != null ? new Date(lastUsedAt.getTime()) : null; - } - - public void setLastUsedAt(Date lastUsedAt) { - this.lastUsedAt = lastUsedAt != null ? new Date(lastUsedAt.getTime()) : null; - } - - public String getUserDn() { - return userDn; - } - - public void setUserDn(String userDn) { - this.userDn = userDn != null ? userDn : ""; - } - - public Date getAuthenticationTime() { - return authenticationTime != null ? new Date(authenticationTime.getTime()) : null; - } - - public void setAuthenticationTime(Date authenticationTime) { - this.authenticationTime = authenticationTime != null ? new Date(authenticationTime.getTime()) : null; - } - - public Boolean getPermissionGranted() { - return permissionGranted; - } - - public void setPermissionGranted(Boolean permissionGranted) { - this.permissionGranted = permissionGranted; - } - - public Map getSessionAttributes() { - if (sessionAttributes == null) { - sessionAttributes = new HashMap(); - } - return sessionAttributes; - } - - public void setSessionAttributes(Map sessionAttributes) { - this.sessionAttributes = sessionAttributes; - } - - public boolean isPersisted() { - return persisted; - } - - public void setPersisted(boolean persisted) { - this.persisted = persisted; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - SimpleSessionState id1 = (SimpleSessionState) o; - - return !(id != null ? !id.equals(id1.id) : id1.id != null); - } - - @Override - public int hashCode() { - return id != null ? id.hashCode() : 0; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(); - sb.append("SessionState"); - sb.append(", dn='").append(dn).append('\''); - sb.append(", id='").append(id).append('\''); - sb.append(", isJwt=").append(isJwt); - sb.append(", lastUsedAt=").append(lastUsedAt); - sb.append(", userDn='").append(userDn).append('\''); - sb.append(", authenticationTime=").append(authenticationTime); - sb.append(", permissionGranted=").append(permissionGranted); - sb.append(", sessionAttributes=").append(sessionAttributes); - sb.append(", persisted=").append(persisted); - sb.append('}'); - return sb.toString(); - } - -} diff --git a/persistence-ldap-sample/src/main/java/org/gluu/ldap/model/SimpleTokenLdap.java b/persistence-ldap-sample/src/main/java/org/gluu/ldap/model/SimpleTokenLdap.java deleted file mode 100644 index 750988925..000000000 --- a/persistence-ldap-sample/src/main/java/org/gluu/ldap/model/SimpleTokenLdap.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.gluu.ldap.model; - -import org.gluu.persist.annotation.*; -import org.gluu.persist.model.base.CustomAttribute; -import org.gluu.util.StringHelper; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -/** - * Created by eugeniuparvan on 1/12/17. - */ -@DataEntry -@ObjectClass(value = "token") -public class SimpleTokenLdap implements Serializable { - - @AttributesList(name = "name", value = "values", sortByName = true) - private List customAttributes = new ArrayList(); - - @DN - private String dn; - - @CustomObjectClass - private String[] customObjectClasses; - - public String getDn() { - return dn; - } - - public void setDn(String dn) { - this.dn = dn; - } - - public List getCustomAttributes() { - return customAttributes; - } - - public void setCustomAttributes(List customAttributes) { - this.customAttributes = customAttributes; - } - - public String getAttribute(String ldapAttribute) { - String attribute = null; - if (ldapAttribute != null && !ldapAttribute.isEmpty()) { - for (CustomAttribute customAttribute : customAttributes) { - if (customAttribute.getName().equals(ldapAttribute)) { - attribute = customAttribute.getValue(); - break; - } - } - } - - return attribute; - } - - public List getAttributeValues(String ldapAttribute) { - List values = null; - if (ldapAttribute != null && !ldapAttribute.isEmpty()) { - for (CustomAttribute customAttribute : customAttributes) { - if (StringHelper.equalsIgnoreCase(customAttribute.getName(), ldapAttribute)) { - values = customAttribute.getValues(); - break; - } - } - } - - return values; - } - - public String[] getCustomObjectClasses() { - return customObjectClasses; - } - - public void setCustomObjectClasses(String[] customObjectClasses) { - this.customObjectClasses = customObjectClasses; - } - -} diff --git a/persistence-ldap-sample/src/main/java/org/gluu/ldap/model/SimpleUser.java b/persistence-ldap-sample/src/main/java/org/gluu/ldap/model/SimpleUser.java deleted file mode 100644 index cfcc94697..000000000 --- a/persistence-ldap-sample/src/main/java/org/gluu/ldap/model/SimpleUser.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.ldap.model; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -import org.gluu.persist.model.base.CustomAttribute; -import org.gluu.persist.annotation.AttributeName; -import org.gluu.persist.annotation.AttributesList; -import org.gluu.persist.annotation.CustomObjectClass; -import org.gluu.persist.annotation.DN; -import org.gluu.persist.annotation.DataEntry; -import org.gluu.persist.annotation.ObjectClass; -import org.gluu.util.StringHelper; - -/** - * @author Yuriy Movchan - * Date: 11/03/2016 - */ -@DataEntry(sortBy = { "uid" }) -@ObjectClass(value = "gluuPerson") -public class SimpleUser implements Serializable { - - private static final long serialVersionUID = -1634191420188575733L; - - @DN - private String dn; - - @AttributeName(name = "uid") - private String userId; - - @AttributesList(name = "name", value = "values", sortByName = true) - private List customAttributes = new ArrayList(); - - @CustomObjectClass - private String[] customObjectClasses; - - public String getDn() { - return dn; - } - - public void setDn(String dn) { - this.dn = dn; - } - - public String getUserId() { - return userId; - } - - public void setUserId(String userId) { - this.userId = userId; - } - - public List getCustomAttributes() { - return customAttributes; - } - - public void setCustomAttributes(List customAttributes) { - this.customAttributes = customAttributes; - } - - public String getAttribute(String ldapAttribute) { - String attribute = null; - if (ldapAttribute != null && !ldapAttribute.isEmpty()) { - for (CustomAttribute customAttribute : customAttributes) { - if (customAttribute.getName().equals(ldapAttribute)) { - attribute = customAttribute.getValue(); - break; - } - } - } - - return attribute; - } - - public List getAttributeValues(String ldapAttribute) { - List values = null; - if (ldapAttribute != null && !ldapAttribute.isEmpty()) { - for (CustomAttribute customAttribute : customAttributes) { - if (StringHelper.equalsIgnoreCase(customAttribute.getName(), ldapAttribute)) { - values = customAttribute.getValues(); - break; - } - } - } - - return values; - } - - public String[] getCustomObjectClasses() { - return customObjectClasses; - } - - public void setCustomObjectClasses(String[] customObjectClasses) { - this.customObjectClasses = customObjectClasses; - } - -} diff --git a/persistence-ldap/pom.xml b/persistence-ldap/pom.xml deleted file mode 100644 index 74afc1742..000000000 --- a/persistence-ldap/pom.xml +++ /dev/null @@ -1,69 +0,0 @@ - - - 4.0.0 - oxcore-persistence-ldap - jar - persistence-ldap - - - org.gluu - oxcore - 4.0.0-SNAPSHOT - - - - - - src/main/resources - true - - **/*.xml - **/services/* - **/*.properties - - - - - - - - - ${project.groupId} - oxcore-util - ${project.version} - - - ${project.groupId} - oxcore-persistence-filter - ${project.version} - - - ${project.groupId} - oxcore-persistence-core - ${project.version} - - - org.gluu - oxcore-persistence-annotation - ${project.version} - - - - com.unboundid - unboundid-ldapsdk - - - - - javax.enterprise - cdi-api - provided - - - javax.inject - javax.inject - - - - - \ No newline at end of file diff --git a/persistence-ldap/src/main/java/org/gluu/persist/ldap/exception/InvalidSimplePageControlException.java b/persistence-ldap/src/main/java/org/gluu/persist/ldap/exception/InvalidSimplePageControlException.java deleted file mode 100644 index 94197b0f9..000000000 --- a/persistence-ldap/src/main/java/org/gluu/persist/ldap/exception/InvalidSimplePageControlException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.ldap.exception; - -import org.gluu.persist.exception.operation.PersistenceException; - -import com.unboundid.ldap.sdk.ResultCode; - -/** - * Invalid page control LDAP exception -- thrown when Simple Page Control returns result without cookie - * - * @author Yuriy Movchan Date: 12/30/2016 - */ -public class InvalidSimplePageControlException extends PersistenceException { - - private static final long serialVersionUID = 1756816743469359856L; - - private ResultCode resultCode; - - public InvalidSimplePageControlException(String message) { - super(message); - } - - public InvalidSimplePageControlException(ResultCode resultCode, String message) { - super(message); - - this.resultCode = resultCode; - } - - public ResultCode getResultCode() { - return resultCode; - } - -} diff --git a/persistence-ldap/src/main/java/org/gluu/persist/ldap/impl/LdapBatchOperationWraper.java b/persistence-ldap/src/main/java/org/gluu/persist/ldap/impl/LdapBatchOperationWraper.java deleted file mode 100644 index f7116a4a6..000000000 --- a/persistence-ldap/src/main/java/org/gluu/persist/ldap/impl/LdapBatchOperationWraper.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.gluu.persist.ldap.impl; - -import java.util.ArrayList; -import java.util.List; - -import org.gluu.persist.model.BatchOperation; -import org.gluu.persist.reflect.property.PropertyAnnotation; - -import com.unboundid.ldap.sdk.SearchResult; -import com.unboundid.ldap.sdk.SearchResultEntry; - -/** - * LDAP batch operation wrapper - * - * @author Yuriy Movchan Date: 02/07/2010 - */ -public class LdapBatchOperationWraper { - - private LdapEntryManager ldapEntryManager; - private Class entryClass; - private List propertiesAnnotations; - - private BatchOperation batchOperation; - - public LdapBatchOperationWraper(BatchOperation batchOperation) { - this.batchOperation = batchOperation; - } - - public LdapBatchOperationWraper(BatchOperation batchOperation, LdapEntryManager ldapEntryManager, Class entryClass, - List propertiesAnnotations) { - this.batchOperation = batchOperation; - this.ldapEntryManager = ldapEntryManager; - this.entryClass = entryClass; - this.propertiesAnnotations = propertiesAnnotations; - } - - public final BatchOperation getBatchOperation() { - return batchOperation; - } - - public List createEntities(SearchResult searchResult) { - if (ldapEntryManager == null) { - return new ArrayList(0); - } - SearchResultEntry[] searchResultEntry = searchResult.getSearchEntries() - .toArray(new SearchResultEntry[searchResult.getSearchEntries().size()]); - - return ldapEntryManager.createEntities(entryClass, propertiesAnnotations, searchResultEntry); - } - -} diff --git a/persistence-ldap/src/main/java/org/gluu/persist/ldap/impl/LdapEntryManager.java b/persistence-ldap/src/main/java/org/gluu/persist/ldap/impl/LdapEntryManager.java deleted file mode 100644 index 5bc8689ad..000000000 --- a/persistence-ldap/src/main/java/org/gluu/persist/ldap/impl/LdapEntryManager.java +++ /dev/null @@ -1,971 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.ldap.impl; - -import java.io.Serializable; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.commons.codec.binary.Base64; -import org.gluu.persist.event.DeleteNotifier; -import org.gluu.persist.exception.AuthenticationException; -import org.gluu.persist.exception.EntryDeleteException; -import org.gluu.persist.exception.EntryPersistenceException; -import org.gluu.persist.exception.MappingException; -import org.gluu.persist.exception.operation.ConnectionException; -import org.gluu.persist.exception.operation.SearchException; -import org.gluu.persist.exception.operation.SearchScopeException; -import org.gluu.persist.impl.BaseEntryManager; -import org.gluu.persist.ldap.operation.LdapOperationService; -import org.gluu.persist.ldap.operation.impl.LdapOperationsServiceImpl; -import org.gluu.persist.model.AttributeData; -import org.gluu.persist.model.AttributeDataModification; -import org.gluu.persist.model.AttributeDataModification.AttributeModificationType; -import org.gluu.persist.model.BatchOperation; -import org.gluu.persist.model.DefaultBatchOperation; -import org.gluu.persist.model.PagedResult; -import org.gluu.persist.model.SearchScope; -import org.gluu.persist.model.SortOrder; -import org.gluu.persist.model.base.DeletableEntity; -import org.gluu.persist.reflect.property.PropertyAnnotation; -import org.gluu.search.filter.Filter; -import org.gluu.util.ArrayHelper; -import org.gluu.util.StringHelper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.unboundid.ldap.sdk.Attribute; -import com.unboundid.ldap.sdk.LDAPConnection; -import com.unboundid.ldap.sdk.Modification; -import com.unboundid.ldap.sdk.ModificationType; -import com.unboundid.ldap.sdk.ResultCode; -import com.unboundid.ldap.sdk.SearchResult; -import com.unboundid.ldap.sdk.SearchResultEntry; -import com.unboundid.util.StaticUtils; - -/** - * LDAP Entry Manager - * - * @author Yuriy Movchan Date: 10.07.2010 - */ -public class LdapEntryManager extends BaseEntryManager implements Serializable { - - private static final long serialVersionUID = -2544614410981223105L; - - private static final Logger LOG = LoggerFactory.getLogger(LdapEntryManager.class); - - private static final LdapFilterConverter LDAP_FILTER_CONVERTER = new LdapFilterConverter(); - private static final LdapSearchScopeConverter LDAP_SEARCH_SCOPE_CONVERTER = new LdapSearchScopeConverter(); - - private LdapOperationsServiceImpl operationService; - private List subscribers; - - public LdapEntryManager() { - } - - public LdapEntryManager(LdapOperationsServiceImpl operationService) { - this.operationService = operationService; - subscribers = new LinkedList(); - } - - @Override - public boolean destroy() { - if (this.operationService == null) { - return true; - } - - return this.operationService.destroy(); - } - - public LdapOperationsServiceImpl getOperationService() { - return operationService; - } - - @Override - public void addDeleteSubscriber(DeleteNotifier subscriber) { - subscribers.add(subscriber); - } - - @Override - public void removeDeleteSubscriber(DeleteNotifier subscriber) { - subscribers.remove(subscriber); - } - - @Override - public T merge(T entry) { - Class entryClass = entry.getClass(); - checkEntryClass(entryClass, true); - if (isSchemaEntry(entryClass)) { - if (getSupportedLDAPVersion() > 2) { - return merge(entry, true, AttributeModificationType.ADD); - } else { - throw new UnsupportedOperationException("Server doesn't support dynamic schema modifications"); - } - } else { - return merge(entry, false, null); - } - } - - @Override - protected void updateMergeChanges(String baseDn, T entry, boolean isSchemaUpdate, Class entryClass, Map attributesFromLdapMap, - List attributeDataModifications) { - // Update object classes if entry contains custom object classes - if (getSupportedLDAPVersion() > 2) { - if (!isSchemaUpdate) { - String[] objectClasses = getObjectClasses(entry, entryClass); - String[] objectClassesFromLdap = attributesFromLdapMap.get(OBJECT_CLASS.toLowerCase()).getStringValues(); - - if (!Arrays.equals(objectClassesFromLdap, objectClasses)) { - attributeDataModifications.add(new AttributeDataModification(AttributeModificationType.REPLACE, - new AttributeData(OBJECT_CLASS, objectClasses), new AttributeData(OBJECT_CLASS, objectClassesFromLdap))); - } - } - } - } - - @Override - public void remove(Object entry) { - Class entryClass = entry.getClass(); - checkEntryClass(entryClass, true); - if (isSchemaEntry(entryClass)) { - if (getSupportedLDAPVersion() > 2) { - merge(entry, true, AttributeModificationType.REMOVE); - } else { - throw new UnsupportedOperationException("Server doesn't support dynamic schema modifications"); - } - return; - } - - Object dnValue = getDNValue(entry, entryClass); - - LOG.debug(String.format("LDAP entry to remove: %s", dnValue.toString())); - - remove(dnValue.toString()); - } - - @Override - protected void persist(String dn, List attributes) { - List ldapAttributes = new ArrayList(attributes.size()); - for (AttributeData attribute : attributes) { - String attributeName = attribute.getName(); - String[] attributeValues = attribute.getStringValues(); - - if (ArrayHelper.isNotEmpty(attributeValues) && StringHelper.isNotEmpty(attributeValues[0])) { - if (operationService.isCertificateAttribute(attributeName)) { - byte[][] binaryValues = toBinaryValues(attributeValues); - - ldapAttributes.add(new Attribute(attributeName + ";binary", binaryValues)); - } else { - ldapAttributes.add(new Attribute(attributeName, attributeValues)); - } - } - } - - // Persist entry - try { - boolean result = this.operationService.addEntry(dn, ldapAttributes); - if (!result) { - throw new EntryPersistenceException(String.format("Failed to persist entry: %s", dn)); - } - } catch (ConnectionException ex) { - throw new EntryPersistenceException(String.format("Failed to persist entry: %s", dn), ex.getCause()); - } catch (Exception ex) { - throw new EntryPersistenceException(String.format("Failed to persist entry: %s", dn), ex); - } - } - - @Override - public void merge(String dn, List attributeDataModifications) { - // Update entry - try { - List modifications = new ArrayList(attributeDataModifications.size()); - for (AttributeDataModification attributeDataModification : attributeDataModifications) { - AttributeData attribute = attributeDataModification.getAttribute(); - AttributeData oldAttribute = attributeDataModification.getOldAttribute(); - - String attributeName = null; - String[] attributeValues = null; - if (attribute != null) { - attributeName = attribute.getName(); - attributeValues = attribute.getStringValues(); - } - - String oldAttributeName = null; - String[] oldAttributeValues = null; - if (oldAttribute != null) { - oldAttributeName = oldAttribute.getName(); - oldAttributeValues = oldAttribute.getStringValues(); - } - - Modification modification = null; - if (AttributeModificationType.ADD.equals(attributeDataModification.getModificationType())) { - modification = createModification(ModificationType.ADD, attributeName, attributeValues); - } else { - if (AttributeModificationType.REMOVE.equals(attributeDataModification.getModificationType())) { - modification = createModification(ModificationType.DELETE, oldAttributeName, oldAttributeValues); - } else if (AttributeModificationType.REPLACE.equals(attributeDataModification.getModificationType())) { - if (attributeValues.length == 1) { - modification = createModification(ModificationType.REPLACE, attributeName, attributeValues); - } else { - String[] oldValues = ArrayHelper.arrayClone(oldAttributeValues); - String[] newValues = ArrayHelper.arrayClone(attributeValues); - - Arrays.sort(oldValues); - Arrays.sort(newValues); - - boolean[] retainOldValues = new boolean[oldValues.length]; - Arrays.fill(retainOldValues, false); - - List addValues = new ArrayList(); - List removeValues = new ArrayList(); - - // Add new values - for (String value : newValues) { - int idx = Arrays.binarySearch(oldValues, value, new Comparator() { - @Override - public int compare(String o1, String o2) { - return o1.toLowerCase().compareTo(o2.toLowerCase()); - } - }); - if (idx >= 0) { - // Old values array contains new value. Retain - // old value - retainOldValues[idx] = true; - } else { - // This is new value - addValues.add(value); - } - } - - // Remove values which we don't have in new values - for (int i = 0; i < oldValues.length; i++) { - if (!retainOldValues[i]) { - removeValues.add(oldValues[i]); - } - } - - if (removeValues.size() > 0) { - Modification removeModification = createModification(ModificationType.DELETE, attributeName, - removeValues.toArray(new String[removeValues.size()])); - modifications.add(removeModification); - } - - if (addValues.size() > 0) { - Modification addModification = createModification(ModificationType.ADD, attributeName, - addValues.toArray(new String[addValues.size()])); - modifications.add(addModification); - } - } - } - } - - if (modification != null) { - modifications.add(modification); - } - } - - if (modifications.size() > 0) { - boolean result = this.operationService.updateEntry(dn, modifications); - if (!result) { - throw new EntryPersistenceException(String.format("Failed to update entry: %s", dn)); - } - } - } catch (ConnectionException ex) { - throw new EntryPersistenceException(String.format("Failed to update entry: %s", dn), ex.getCause()); - } catch (Exception ex) { - throw new EntryPersistenceException(String.format("Failed to update entry: %s", dn), ex); - } - } - - @Override - public void remove(String dn) { - // Remove entry - try { - for (DeleteNotifier subscriber : subscribers) { - subscriber.onBeforeRemove(dn); - } - this.operationService.delete(dn); - for (DeleteNotifier subscriber : subscribers) { - subscriber.onAfterRemove(dn); - } - } catch (Exception ex) { - throw new EntryDeleteException(String.format("Failed to remove entry: %s", dn), ex); - } - } - - @Override - public int remove(String baseDN, Class entryClass, Filter filter, int count) { - if (StringHelper.isEmptyString(baseDN)) { - throw new MappingException("Base DN to find entries is null"); - } - - // Check entry class - checkEntryClass(entryClass, false); - String[] objectClasses = getTypeObjectClasses(entryClass); - List propertiesAnnotations = getEntryPropertyAnnotations(entryClass); - - // Find entries - Filter searchFilter; - if (objectClasses.length > 0) { - searchFilter = addObjectClassFilter(filter, objectClasses); - } else { - searchFilter = filter; - } - - DeleteBatchOperation batchOperation = new DeleteBatchOperation(this); - SearchResult searchResult = null; - try { - LdapBatchOperationWraper batchOperationWraper = new LdapBatchOperationWraper(batchOperation, this, entryClass, - propertiesAnnotations); - searchResult = this.operationService.search(baseDN, toLdapFilter(searchFilter), toLdapSearchScope(SearchScope.SUB), batchOperationWraper, - 0, 100, count, null, LdapOperationsServiceImpl.DN); - - } catch (Exception ex) { - throw new EntryDeleteException(String.format("Failed to delete entries with baseDN: %s, filter: %s", baseDN, searchFilter), ex); - } - - if (!ResultCode.SUCCESS.equals(searchResult.getResultCode())) { - throw new EntryDeleteException(String.format("Failed to delete entries with baseDN: %s, filter: %s", baseDN, searchFilter)); - } - - return batchOperation.getCountEntries(); - } - - @Override - public void removeRecursively(String dn) { - try { - if (this.operationService.getConnectionProvider().isSupportsSubtreeDeleteRequestControl()) { - for (DeleteNotifier subscriber : subscribers) { - subscriber.onBeforeRemove(dn); - } - this.operationService.deleteRecursively(dn); - for (DeleteNotifier subscriber : subscribers) { - subscriber.onAfterRemove(dn); - } - } else { - removeSubtreeThroughIteration(dn); - } - } catch (Exception ex) { - throw new EntryDeleteException(String.format("Failed to remove entry: %s", dn), ex); - } - } - - private void removeSubtreeThroughIteration(String dn) { - SearchScope scope = SearchScope.SUB; - - SearchResult searchResult = null; - try { - searchResult = this.operationService.search(dn, toLdapFilter(Filter.createPresenceFilter("objectClass")), toLdapSearchScope(scope), null, 0, 0, 0, null, "dn"); - if (!ResultCode.SUCCESS.equals(searchResult.getResultCode())) { - throw new EntryPersistenceException(String.format("Failed to find sub-entries of entry '%s' for removal", dn)); - } - } catch (SearchScopeException ex) { - throw new AuthenticationException(String.format("Failed to convert scope: %s", scope), ex); - } catch (SearchException ex) { - throw new EntryDeleteException(String.format("Failed to find sub-entries of entry '%s' for removal", dn), ex); - } - - List removeEntriesDn = new ArrayList(searchResult.getEntryCount()); - for (SearchResultEntry searchResultEntry : searchResult.getSearchEntries()) { - removeEntriesDn.add(searchResultEntry.getDN()); - } - - Collections.sort(removeEntriesDn, LINE_LENGHT_COMPARATOR); - - for (String removeEntryDn : removeEntriesDn) { - remove(removeEntryDn); - } - } - - @Override - protected List find(String dn, Map propertiesAnnotationsMap, String... ldapReturnAttributes) { - try { - // Load entry - SearchResultEntry entry = this.operationService.lookup(dn, ldapReturnAttributes); - List result = getAttributeDataList(entry); - if (result != null) { - return result; - } - } catch (Exception ex) { - throw new EntryPersistenceException(String.format("Failed to find entry: %s", dn), ex); - } - - throw new EntryPersistenceException(String.format("Failed to find entry: %s", dn)); - } - - @Override - public List findEntries(String baseDN, Class entryClass, Filter filter, SearchScope scope, String[] ldapReturnAttributes, - BatchOperation batchOperation, int start, int count, int chunkSize) { - if (StringHelper.isEmptyString(baseDN)) { - throw new MappingException("Base DN to find entries is null"); - } - - // Check entry class - checkEntryClass(entryClass, false); - String[] objectClasses = getTypeObjectClasses(entryClass); - List propertiesAnnotations = getEntryPropertyAnnotations(entryClass); - String[] currentLdapReturnAttributes = ldapReturnAttributes; - if (ArrayHelper.isEmpty(currentLdapReturnAttributes)) { - currentLdapReturnAttributes = getAttributes(null, propertiesAnnotations, false); - } - - // Find entries - Filter searchFilter; - if (objectClasses.length > 0) { - searchFilter = addObjectClassFilter(filter, objectClasses); - } else { - searchFilter = filter; - } - SearchResult searchResult = null; - try { - LdapBatchOperationWraper batchOperationWraper = new LdapBatchOperationWraper(batchOperation, this, entryClass, - propertiesAnnotations); - searchResult = this.operationService.search(baseDN, toLdapFilter(searchFilter), toLdapSearchScope(scope), batchOperationWraper, - start, chunkSize, count, null, currentLdapReturnAttributes); - } catch (Exception ex) { - throw new EntryPersistenceException(String.format("Failed to find entries with baseDN: %s, filter: %s", baseDN, searchFilter), ex); - } - - if (!ResultCode.SUCCESS.equals(searchResult.getResultCode())) { - throw new EntryPersistenceException(String.format("Failed to find entries with baseDN: %s, filter: %s", baseDN, searchFilter)); - } - - if (searchResult.getEntryCount() == 0) { - return new ArrayList(0); - } - - List entries = createEntities(entryClass, propertiesAnnotations, - searchResult.getSearchEntries().toArray(new SearchResultEntry[searchResult.getSearchEntries().size()])); - - // Default sort if needed - sortEntriesIfNeeded(entryClass, entries); - - return entries; - } - - @Override - public PagedResult findPagedEntries(String baseDN, Class entryClass, Filter filter, String[] ldapReturnAttributes, String sortBy, - SortOrder sortOrder, int start, int count, int chunkSize) { - if (StringHelper.isEmptyString(baseDN)) { - throw new MappingException("Base DN to find entries is null"); - } - - // Check entry class - checkEntryClass(entryClass, false); - String[] objectClasses = getTypeObjectClasses(entryClass); - List propertiesAnnotations = getEntryPropertyAnnotations(entryClass); - String[] currentLdapReturnAttributes = ldapReturnAttributes; - if (ArrayHelper.isEmpty(currentLdapReturnAttributes)) { - currentLdapReturnAttributes = getAttributes(null, propertiesAnnotations, false); - } - - // Find entries - Filter searchFilter; - if (objectClasses.length > 0) { - searchFilter = addObjectClassFilter(filter, objectClasses); - } else { - searchFilter = filter; - } - - List searchResultEntries; - PagedResult vlvResponse = new PagedResult(); - try { - searchResultEntries = this.operationService.searchSearchResultEntryList(baseDN, toLdapFilter(searchFilter), - toLdapSearchScope(SearchScope.SUB), start, count, chunkSize, sortBy, sortOrder, vlvResponse, currentLdapReturnAttributes); - } catch (Exception ex) { - throw new EntryPersistenceException(String.format("Failed to find entries with baseDN: %s, filter: %s", baseDN, searchFilter), ex); - } - - List entries = new ArrayList(0); - if (searchResultEntries.size() > 0) { - entries = createEntitiesVirtualListView(entryClass, propertiesAnnotations, searchResultEntries.toArray(new SearchResultEntry[]{})); - } - vlvResponse.setEntries(entries); - - return vlvResponse; - - } - - @Deprecated - public List findEntriesVirtualListView(String baseDN, Class entryClass, Filter filter, int start, int count, String sortBy, - SortOrder sortOrder, PagedResult vlvResponse, String[] ldapReturnAttributes) { - - if (StringHelper.isEmptyString(baseDN)) { - throw new MappingException("Base DN to find entries is null"); - } - - // Check entry class - checkEntryClass(entryClass, false); - String[] objectClasses = getTypeObjectClasses(entryClass); - List propertiesAnnotations = getEntryPropertyAnnotations(entryClass); - String[] currentLdapReturnAttributes = ldapReturnAttributes; - if (ArrayHelper.isEmpty(currentLdapReturnAttributes)) { - currentLdapReturnAttributes = getAttributes(null, propertiesAnnotations, false); - } - - // Find entries - Filter searchFilter; - if (objectClasses.length > 0) { - searchFilter = addObjectClassFilter(filter, objectClasses); - } else { - searchFilter = filter; - } - - SearchResult searchResult = null; - try { - - searchResult = this.operationService.searchVirtualListView(baseDN, toLdapFilter(searchFilter), toLdapSearchScope(SearchScope.SUB), - start, count, sortBy, sortOrder, vlvResponse, currentLdapReturnAttributes); - - if (!ResultCode.SUCCESS.equals(searchResult.getResultCode())) { - throw new EntryPersistenceException(String.format("Failed to find entries with baseDN: %s, filter: %s", baseDN, searchFilter)); - } - - } catch (Exception ex) { - throw new EntryPersistenceException(String.format("Failed to find entries with baseDN: %s, filter: %s", baseDN, searchFilter), ex); - } - - if (searchResult.getEntryCount() == 0) { - return new ArrayList(0); - } - - List entries = createEntitiesVirtualListView(entryClass, propertiesAnnotations, - searchResult.getSearchEntries().toArray(new SearchResultEntry[searchResult.getSearchEntries().size()])); - - return entries; - } - - @Override - protected boolean contains(String baseDN, Class entryClass, List propertiesAnnotations, Filter filter, String[] objectClasses, String[] ldapReturnAttributes) { - if (StringHelper.isEmptyString(baseDN)) { - throw new MappingException("Base DN to check contain entries is null"); - } - - // Create filter - Filter searchFilter; - if (objectClasses.length > 0) { - searchFilter = addObjectClassFilter(filter, objectClasses); - } else { - searchFilter = filter; - } - - SearchScope scope = SearchScope.SUB; - - SearchResult searchResult = null; - try { - searchResult = this.operationService.search(baseDN, toLdapFilter(searchFilter), toLdapSearchScope(scope), null, 0, 1, 1, null, ldapReturnAttributes); - if ((searchResult == null) || !ResultCode.SUCCESS.equals(searchResult.getResultCode())) { - throw new EntryPersistenceException(String.format("Failed to find entry with baseDN: %s, filter: %s", baseDN, searchFilter)); - } - } catch (SearchScopeException ex) { - throw new AuthenticationException(String.format("Failed to convert scope: %s", scope), ex); - } catch (SearchException ex) { - if (!(ResultCode.NO_SUCH_OBJECT_INT_VALUE == ex.getErrorCode())) { - throw new EntryPersistenceException(String.format("Failed to find entry with baseDN: %s, filter: %s", baseDN, searchFilter), ex); - } - } - - return (searchResult != null) && (searchResult.getEntryCount() > 0); - } - - protected List createEntities(Class entryClass, List propertiesAnnotations, - SearchResultEntry... searchResultEntries) { - List result = new ArrayList(searchResultEntries.length); - Map> entriesAttributes = new HashMap>(100); - - int count = 0; - for (int i = 0; i < searchResultEntries.length; i++) { - count++; - SearchResultEntry entry = searchResultEntries[i]; - entriesAttributes.put(entry.getDN(), getAttributeDataList(entry)); - - // Remove reference to allow java clean up object - searchResultEntries[i] = null; - - // Allow java to clean up temporary objects - if (count >= 100) { - List currentResult = createEntities(entryClass, propertiesAnnotations, entriesAttributes); - result.addAll(currentResult); - - entriesAttributes = new HashMap>(100); - count = 0; - } - } - - List currentResult = createEntities(entryClass, propertiesAnnotations, entriesAttributes); - result.addAll(currentResult); - - return result; - } - - @Deprecated - private List createEntitiesVirtualListView(Class entryClass, List propertiesAnnotations, - SearchResultEntry... searchResultEntries) { - - List result = new LinkedList(); - Map> entriesAttributes = new LinkedHashMap>(100); - - int count = 0; - for (int i = 0; i < searchResultEntries.length; i++) { - - count++; - - SearchResultEntry entry = searchResultEntries[i]; - - LinkedList attributeDataLinkedList = new LinkedList(); - attributeDataLinkedList.addAll(getAttributeDataList(entry)); - entriesAttributes.put(entry.getDN(), attributeDataLinkedList); - - // Remove reference to allow java clean up object - searchResultEntries[i] = null; - - // Allow java to clean up temporary objects - if (count >= 100) { - - List currentResult = new LinkedList(); - currentResult.addAll(createEntities(entryClass, propertiesAnnotations, entriesAttributes, false)); - result.addAll(currentResult); - - entriesAttributes = new LinkedHashMap>(100); - count = 0; - } - } - - List currentResult = createEntities(entryClass, propertiesAnnotations, entriesAttributes, false); - result.addAll(currentResult); - - return result; - } - - private List getAttributeDataList(SearchResultEntry entry) { - if (entry == null) { - return null; - } - - List result = new ArrayList(); - for (Attribute attribute : entry.getAttributes()) { - String[] attributeValueStrings = NO_STRINGS; - String attributeName = attribute.getName(); - if (LOG.isTraceEnabled()) { - if (attribute.needsBase64Encoding()) { - LOG.trace("Found binary attribute: " + attributeName + ". Is defined in LDAP config: " - + operationService.isBinaryAttribute(attributeName)); - } - } - - attributeValueStrings = attribute.getValues(); - if (attribute.needsBase64Encoding()) { - boolean binaryAttribute = operationService.isBinaryAttribute(attributeName); - boolean certificateAttribute = operationService.isCertificateAttribute(attributeName); - - if (binaryAttribute || certificateAttribute) { - byte[][] attributeValues = attribute.getValueByteArrays(); - if (attributeValues != null) { - attributeValueStrings = new String[attributeValues.length]; - for (int i = 0; i < attributeValues.length; i++) { - attributeValueStrings[i] = Base64.encodeBase64String(attributeValues[i]); - LOG.trace("Binary attribute: " + attribute.getName() + " value (hex): " - + org.apache.commons.codec.binary.Hex.encodeHexString(attributeValues[i]) + " value (base64): " - + attributeValueStrings[i]); - } - } - } - if (certificateAttribute) { - attributeName = operationService.getCertificateAttributeName(attributeName); - } - } - - boolean multiValued = attributeValueStrings.length > 1; - AttributeData tmpAttribute = new AttributeData(attributeName, attributeValueStrings, multiValued); - result.add(tmpAttribute); - } - - return result; - } - - @Override - public boolean authenticate(String baseDN, String userName, String password) { - SearchScope scope = SearchScope.SUB; - try { - Filter filter = Filter.createEqualityFilter(LdapOperationsServiceImpl.UID, userName); - SearchResult searchResult = operationService.search(baseDN, toLdapFilter(filter), toLdapSearchScope(scope), null, 0, 1, 1, null, (String[]) null); - if ((searchResult == null) || (searchResult.getEntryCount() != 1)) { - return false; - } - - String bindDn = searchResult.getSearchEntries().get(0).getDN(); - - return operationService.authenticate(bindDn, password); - } catch (ConnectionException ex) { - throw new AuthenticationException(String.format("Failed to authenticate user: %s", userName), ex); - } catch (SearchScopeException ex) { - throw new AuthenticationException(String.format("Failed to convert scope: %s", scope), ex); - } catch (SearchException ex) { - throw new AuthenticationException(String.format("Failed to find user DN: %s", userName), ex); - } - } - - @Override - public boolean authenticate(String bindDn, String password) { - try { - return operationService.authenticate(bindDn, password); - } catch (ConnectionException ex) { - throw new AuthenticationException(String.format("Failed to authenticate DN: %s", bindDn), ex); - } - } - - @Override - public int countEntries(String baseDN, Class entryClass, Filter filter) { - return countEntries(baseDN, entryClass, filter, null); - } - - @Override - public int countEntries(String baseDN, Class entryClass, Filter filter, SearchScope scope) { - if (StringHelper.isEmptyString(baseDN)) { - throw new MappingException("Base DN to count entries is null"); - } - - // Check entry class - checkEntryClass(entryClass, false); - String[] objectClasses = getTypeObjectClasses(entryClass); - - // Find entries - Filter searchFilter; - if (objectClasses.length > 0) { - searchFilter = addObjectClassFilter(filter, objectClasses); - } else { - searchFilter = filter; - } - - SearchScope searchScope = scope; - if (searchScope == null) { - searchScope = SearchScope.SUB; - } - - String[] ldapReturnAttributes; - CountBatchOperation batchOperation; - if (SearchScope.BASE == searchScope) { - ldapReturnAttributes = new String[] { "numsubordinates" }; // Don't load attributes - batchOperation = null; - } else { - ldapReturnAttributes = new String[] { "" }; // Don't load attributes - batchOperation = new CountBatchOperation(); - } - - SearchResult searchResult; - try { - LdapBatchOperationWraper batchOperationWraper = null; - if (batchOperation != null) { - batchOperationWraper = new LdapBatchOperationWraper(batchOperation); - } - searchResult = operationService.search(baseDN, toLdapFilter(searchFilter), toLdapSearchScope(searchScope), batchOperationWraper, 0, 100, 0, null, - ldapReturnAttributes); - } catch (Exception ex) { - throw new EntryPersistenceException( - String.format("Failed to calculate the number of entries with baseDN: %s, filter: %s", baseDN, searchFilter), ex); - } - - if (SearchScope.BASE != searchScope) { - return batchOperation.getCountEntries(); - } - - if (searchResult.getEntryCount() != 1) { - throw new EntryPersistenceException(String.format("Failed to calculate the number of entries due to missing result entry with baseDN: %s, filter: %s", baseDN, searchFilter)); - } - - Long result = searchResult.getSearchEntries().get(0).getAttributeValueAsLong("numsubordinates"); - if (result == null) { - throw new EntryPersistenceException(String.format("Failed to calculate the number of entries due to missing attribute 'numsubordinates' with baseDN: %s, filter: %s", baseDN, searchFilter)); - } - - return result.intValue(); - } - - @Override - public String encodeTime(String baseDN, Date date) { - if (date == null) { - return null; - } - - return StaticUtils.encodeGeneralizedTime(date); - } - - @Override - protected String encodeTime(Date date) { - return encodeTime(null, date); - } - - @Override - public Date decodeTime(String baseDN, String date) { - if (date == null) { - return null; - } - - try { - return StaticUtils.decodeGeneralizedTime(date); - } catch (ParseException ex) { - LOG.error("Failed to parse generalized time {}", date, ex); - } - - return null; - } - - @Override - protected Date decodeTime(String date) { - return decodeTime(null, date); - } - - public boolean loadLdifFileContent(String ldifFileContent) { - LDAPConnection connection = null; - try { - connection = operationService.getConnection(); - ResultCode result = LdifDataUtility.instance().importLdifFileContent(connection, ldifFileContent); - return ResultCode.SUCCESS.equals(result); - } catch (Exception ex) { - LOG.error("Failed to load ldif file", ex); - return false; - } finally { - if (connection != null) { - operationService.releaseConnection(connection); - } - } - } - - @Override - public List exportEntry(String dn) { - try { - SearchResultEntry searchResultEntry = this.operationService.lookup(dn, (String[]) null); - - List result = getAttributeDataList(searchResultEntry); - if (result != null) { - return result; - } - - return null; - } catch (ConnectionException ex) { - throw new EntryPersistenceException(String.format("Failed to find entry: %s", dn), ex); - } - } - - @Override - public void importEntry(String dn, List data) { - persist(dn, data); - } - - public int getSupportedLDAPVersion() { - return this.operationService.getSupportedLDAPVersion(); - } - - private Modification createModification(final ModificationType modificationType, final String attributeName, final String... attributeValues) { - String realAttributeName = attributeName; - if (operationService.isCertificateAttribute(realAttributeName)) { - realAttributeName += ";binary"; - byte[][] binaryValues = toBinaryValues(attributeValues); - - return new Modification(modificationType, realAttributeName, binaryValues); - } - - return new Modification(modificationType, realAttributeName, attributeValues); - } - - private com.unboundid.ldap.sdk.Filter toLdapFilter(Filter genericFilter) throws SearchException { - return LDAP_FILTER_CONVERTER.convertToLdapFilter(genericFilter); - } - - private com.unboundid.ldap.sdk.SearchScope toLdapSearchScope(SearchScope scope) throws SearchScopeException { - return LDAP_SEARCH_SCOPE_CONVERTER.convertToLdapSearchScope(scope); - } - - @Override - public boolean hasBranchesSupport(String dn) { - return true; - } - - @Override - public String getPersistenceType(String primaryKey) { - return LdapEntryManagerFactory.PERSISTANCE_TYPE; - } - - @Override - public String[] getObjectClasses(Object entry, Class entryClass) { - String[] ojectClasses = super.getObjectClasses(entry, entryClass); - - Set objecClassSet = new HashSet(); - - // Add in LDAP implementation "top" by default - objecClassSet.add("top"); - objecClassSet.addAll(Arrays.asList(ojectClasses)); - return objecClassSet.toArray(new String[0]); - } - - private static class CountBatchOperation extends DefaultBatchOperation { - - private int countEntries = 0; - - @Override - public void performAction(List entries) { - } - - @Override - public boolean collectSearchResult(int size) { - countEntries += size; - return false; - } - - public int getCountEntries() { - return countEntries; - } - } - - private static final class DeleteBatchOperation extends DefaultBatchOperation { - - private int countEntries = 0; - private LdapEntryManager ldapEntryManager; - - public DeleteBatchOperation(LdapEntryManager ldapEntryManager) { - this.ldapEntryManager = ldapEntryManager; - } - - @Override - public void performAction(List entries) { - for (DeletableEntity entity : entries) { - try { - if (ldapEntryManager.hasBranchesSupport(entity.getDn())) { - ldapEntryManager.removeRecursively(entity.getDn()); - } else { - ldapEntryManager.remove(entity.getDn()); - } - LOG.trace("Removed {}", entity.getDn()); - } catch (Exception e) { - LOG.error("Failed to remove entry, dn: " + entity.getDn(), e); - } - } - } - - @Override - public boolean collectSearchResult(int size) { - countEntries += size; - return false; - } - - public int getCountEntries() { - return countEntries; - } - } - -} diff --git a/persistence-ldap/src/main/java/org/gluu/persist/ldap/impl/LdapEntryManagerFactory.java b/persistence-ldap/src/main/java/org/gluu/persist/ldap/impl/LdapEntryManagerFactory.java deleted file mode 100644 index ce1ffc99e..000000000 --- a/persistence-ldap/src/main/java/org/gluu/persist/ldap/impl/LdapEntryManagerFactory.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.gluu.persist.ldap.impl; - -import java.util.HashMap; -import java.util.Properties; - -import javax.enterprise.context.ApplicationScoped; - -import org.gluu.persist.PersistenceEntryManagerFactory; -import org.gluu.persist.exception.operation.ConfigurationException; -import org.gluu.persist.ldap.operation.impl.LdapAuthConnectionProvider; -import org.gluu.persist.ldap.operation.impl.LdapConnectionProvider; -import org.gluu.persist.ldap.operation.impl.LdapOperationsServiceImpl; -import org.gluu.persist.service.BaseFactoryService; -import org.gluu.util.PropertiesHelper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * LDAP Entry Manager Factory - * - * @author Yuriy Movchan Date: 02/02/2018 - */ -@ApplicationScoped -public class LdapEntryManagerFactory implements PersistenceEntryManagerFactory { - - public static final String PERSISTANCE_TYPE = "ldap"; - public static final String LDAP_DEFAULT_PROPERTIES_FILE = "gluu-ldap.properties"; - - private static final Logger LOG = LoggerFactory.getLogger(LdapEntryManagerFactory.class); - - @Override - public String getPersistenceType() { - return PERSISTANCE_TYPE; - } - - @Override - public HashMap getConfigurationFileNames() { - HashMap confs = new HashMap(); - confs.put(PERSISTANCE_TYPE, LDAP_DEFAULT_PROPERTIES_FILE); - - return confs; - } - - @Override - public LdapEntryManager createEntryManager(Properties conf) { - Properties entryManagerConf = PropertiesHelper.filterProperties(conf, PERSISTANCE_TYPE); - - LdapConnectionProvider connectionProvider = new LdapConnectionProvider(entryManagerConf); - if (!connectionProvider.isCreated()) { - throw new ConfigurationException( - String.format("Failed to create LDAP connection pool! Result code: '%s'", connectionProvider.getCreationResultCode())); - } - LOG.debug("Created connectionProvider '{}' with code '{}'", connectionProvider, connectionProvider.getCreationResultCode()); - - LdapConnectionProvider bindConnectionProvider = new LdapAuthConnectionProvider(entryManagerConf); - if (!bindConnectionProvider.isCreated()) { - throw new ConfigurationException( - String.format("Failed to create LDAP bind connection pool! Result code: '%s'", bindConnectionProvider.getCreationResultCode())); - } - LOG.debug("Created bindConnectionProvider '{}' with code '{}'", bindConnectionProvider, bindConnectionProvider.getCreationResultCode()); - - LdapEntryManager ldapEntryManager = new LdapEntryManager(new LdapOperationsServiceImpl(connectionProvider, bindConnectionProvider)); - LOG.info("Created LdapEntryManager: {}", ldapEntryManager.getOperationService()); - - return ldapEntryManager; - } - - @Override - public void initStandalone(BaseFactoryService persistanceFactoryService) {} - -} diff --git a/persistence-ldap/src/main/java/org/gluu/persist/ldap/impl/LdapFilterConverter.java b/persistence-ldap/src/main/java/org/gluu/persist/ldap/impl/LdapFilterConverter.java deleted file mode 100644 index 18272eb65..000000000 --- a/persistence-ldap/src/main/java/org/gluu/persist/ldap/impl/LdapFilterConverter.java +++ /dev/null @@ -1,147 +0,0 @@ -package org.gluu.persist.ldap.impl; - -import javax.enterprise.context.ApplicationScoped; - -import org.gluu.persist.exception.operation.SearchException; -import org.gluu.search.filter.Filter; -import org.gluu.search.filter.FilterType; -import org.gluu.util.ArrayHelper; - -/** - * Filter to LDAP filter convert - * - * @author Yuriy Movchan Date: 12/15/2017 - */ -@ApplicationScoped -public class LdapFilterConverter { - - public com.unboundid.ldap.sdk.Filter convertToLdapFilter(Filter genericFilter) throws SearchException { - FilterType type = genericFilter.getType(); - if (FilterType.RAW == type) { - try { - return com.unboundid.ldap.sdk.Filter.create(genericFilter.getFilterString()); - } catch (com.unboundid.ldap.sdk.LDAPException ex) { - throw new SearchException("Failed to parse RAW Ldap filter", ex, ex.getResultCode().intValue()); - } - } - - if ((FilterType.NOT == type) || (FilterType.AND == type) || (FilterType.OR == type)) { - Filter[] genericFilters = genericFilter.getFilters(); - com.unboundid.ldap.sdk.Filter[] ldapFilters = new com.unboundid.ldap.sdk.Filter[genericFilters.length]; - - if (genericFilters != null) { - for (int i = 0; i < genericFilters.length; i++) { - ldapFilters[i] = convertToLdapFilter(genericFilters[i]); - } - - if (FilterType.NOT == type) { - return com.unboundid.ldap.sdk.Filter.createNOTFilter(ldapFilters[0]); - } else if (FilterType.AND == type) { - return com.unboundid.ldap.sdk.Filter.createANDFilter(ldapFilters); - } else if (FilterType.OR == type) { - return com.unboundid.ldap.sdk.Filter.createORFilter(ldapFilters); - } - } - } - - if (FilterType.EQUALITY == type) { - String attributeName; - if (ArrayHelper.isEmpty(genericFilter.getFilters())) { - attributeName = genericFilter.getAttributeName(); - } else { - attributeName = convertToLdapFilter(genericFilter.getFilters()[0]).getAttributeName(); - } - return com.unboundid.ldap.sdk.Filter.createEqualityFilter(attributeName, String.valueOf(genericFilter.getAssertionValue())); - } - - if (FilterType.LESS_OR_EQUAL == type) { - return com.unboundid.ldap.sdk.Filter.createLessOrEqualFilter(genericFilter.getAttributeName(), String.valueOf(genericFilter.getAssertionValue())); - } - - if (FilterType.GREATER_OR_EQUAL == type) { - return com.unboundid.ldap.sdk.Filter.createGreaterOrEqualFilter(genericFilter.getAttributeName(), String.valueOf(genericFilter.getAssertionValue())); - } - - if (FilterType.PRESENCE == type) { - return com.unboundid.ldap.sdk.Filter.createPresenceFilter(genericFilter.getAttributeName()); - } - - if (FilterType.APPROXIMATE_MATCH == type) { - return com.unboundid.ldap.sdk.Filter.createApproximateMatchFilter(genericFilter.getAttributeName(), String.valueOf(genericFilter.getAssertionValue())); - } - - if (FilterType.SUBSTRING == type) { - return com.unboundid.ldap.sdk.Filter.createSubstringFilter(genericFilter.getAttributeName(), genericFilter.getSubInitial(), - genericFilter.getSubAny(), genericFilter.getSubFinal()); - } - - if (FilterType.LOWERCASE == type) { - // Return Dummy filter because case sensitivity is defined at LDAP schema level - return com.unboundid.ldap.sdk.Filter.createPresenceFilter(genericFilter.getAttributeName()); - } - - throw new SearchException(String.format("Unknown filter type '%s'", type), com.unboundid.ldap.sdk.ResultCode.PROTOCOL_ERROR_INT_VALUE); - } - - public Filter convertRawLdapFilterToFilter(String rawFilter) throws SearchException { - com.unboundid.ldap.sdk.Filter ldapFilter; - try { - ldapFilter = com.unboundid.ldap.sdk.Filter.create(rawFilter); - } catch (com.unboundid.ldap.sdk.LDAPException ex) { - throw new SearchException("Failed to parse RAW Ldap filter", ex, ex.getResultCode().intValue()); - } - - return convertRawLdapFilterToFilterImpl(ldapFilter); - } - - protected Filter convertRawLdapFilterToFilterImpl(com.unboundid.ldap.sdk.Filter ldapFilter) throws SearchException { - byte type = ldapFilter.getFilterType(); - - if ((com.unboundid.ldap.sdk.Filter.FILTER_TYPE_NOT == type) || (com.unboundid.ldap.sdk.Filter.FILTER_TYPE_AND == type) || (com.unboundid.ldap.sdk.Filter.FILTER_TYPE_OR == type)) { - com.unboundid.ldap.sdk.Filter[] ldapFilters = ldapFilter.getComponents(); - Filter[] genericFilters = new Filter[ldapFilters.length]; - - if (ldapFilters != null) { - for (int i = 0; i < ldapFilters.length; i++) { - genericFilters[i] = convertRawLdapFilterToFilterImpl(ldapFilters[i]); - } - - if (com.unboundid.ldap.sdk.Filter.FILTER_TYPE_NOT == type) { - return Filter.createNOTFilter(genericFilters[0]); - } else if (com.unboundid.ldap.sdk.Filter.FILTER_TYPE_AND == type) { - return Filter.createANDFilter(genericFilters); - } else if (com.unboundid.ldap.sdk.Filter.FILTER_TYPE_OR == type) { - return Filter.createORFilter(genericFilters); - } - } - } - - if (com.unboundid.ldap.sdk.Filter.FILTER_TYPE_EQUALITY == type) { - return Filter.createEqualityFilter(ldapFilter.getAttributeName(), ldapFilter.getAssertionValue()); - } - - if (com.unboundid.ldap.sdk.Filter.FILTER_TYPE_LESS_OR_EQUAL == type) { - return Filter.createLessOrEqualFilter(ldapFilter.getAttributeName(), ldapFilter.getAssertionValue()); - } - - if (com.unboundid.ldap.sdk.Filter.FILTER_TYPE_GREATER_OR_EQUAL == type) { - return Filter.createGreaterOrEqualFilter(ldapFilter.getAttributeName(), ldapFilter.getAssertionValue()); - } - - if (com.unboundid.ldap.sdk.Filter.FILTER_TYPE_PRESENCE == type) { - return Filter.createPresenceFilter(ldapFilter.getAttributeName()); - } - - if (com.unboundid.ldap.sdk.Filter.FILTER_TYPE_APPROXIMATE_MATCH == type) { - return Filter.createApproximateMatchFilter(ldapFilter.getAttributeName(), ldapFilter.getAssertionValue()); - } - - if (com.unboundid.ldap.sdk.Filter.FILTER_TYPE_SUBSTRING == type) { - return Filter.createSubstringFilter(ldapFilter.getAttributeName(), ldapFilter.getSubInitialString(), - ldapFilter.getSubAnyStrings(), ldapFilter.getSubFinalString()); - } - - throw new SearchException(String.format("Unknown filter type '%s'", type), com.unboundid.ldap.sdk.ResultCode.PROTOCOL_ERROR_INT_VALUE); - } - -} diff --git a/persistence-ldap/src/main/java/org/gluu/persist/ldap/impl/LdapSearchScopeConverter.java b/persistence-ldap/src/main/java/org/gluu/persist/ldap/impl/LdapSearchScopeConverter.java deleted file mode 100644 index e6b1ca7a3..000000000 --- a/persistence-ldap/src/main/java/org/gluu/persist/ldap/impl/LdapSearchScopeConverter.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.gluu.persist.ldap.impl; - -import org.gluu.persist.exception.operation.SearchScopeException; -import org.gluu.persist.model.SearchScope; - -/** - * Simple filter without dependency to specific persistence filter mechanism - * - * @author Yuriy Movchan Date: 12/15/2017 - */ -public class LdapSearchScopeConverter { - - public com.unboundid.ldap.sdk.SearchScope convertToLdapSearchScope(SearchScope searchScope) throws SearchScopeException { - if (SearchScope.BASE == searchScope) { - return com.unboundid.ldap.sdk.SearchScope.BASE; - } - if (SearchScope.ONE == searchScope) { - return com.unboundid.ldap.sdk.SearchScope.ONE; - } - if (SearchScope.SUB == searchScope) { - return com.unboundid.ldap.sdk.SearchScope.SUB; - } - - throw new SearchScopeException(String.format("Unknown search scope '%s'", searchScope)); - } - -} diff --git a/persistence-ldap/src/main/java/org/gluu/persist/ldap/impl/LdifDataUtility.java b/persistence-ldap/src/main/java/org/gluu/persist/ldap/impl/LdifDataUtility.java deleted file mode 100644 index 1d06fead5..000000000 --- a/persistence-ldap/src/main/java/org/gluu/persist/ldap/impl/LdifDataUtility.java +++ /dev/null @@ -1,346 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.ldap.impl; - -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.StringReader; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; - -import org.apache.commons.io.IOUtils; -import org.gluu.util.StringHelper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.unboundid.ldap.sdk.ChangeType; -import com.unboundid.ldap.sdk.Entry; -import com.unboundid.ldap.sdk.Filter; -import com.unboundid.ldap.sdk.LDAPConnection; -import com.unboundid.ldap.sdk.LDAPException; -import com.unboundid.ldap.sdk.LDAPSearchException; -import com.unboundid.ldap.sdk.ResultCode; -import com.unboundid.ldap.sdk.SearchResult; -import com.unboundid.ldap.sdk.SearchResultEntry; -import com.unboundid.ldap.sdk.SearchScope; -import com.unboundid.ldif.LDIFChangeRecord; -import com.unboundid.ldif.LDIFException; -import com.unboundid.ldif.LDIFReader; - -/** - * Utility class to import ldif file to LDAP. - * - * @author Yuriy Movchan Date: 08.06.2010 - */ -public final class LdifDataUtility { - - private static final Logger LOG = LoggerFactory.getLogger(LdifDataUtility.class); - - // Just define the singleton as a static field in a separate class. - // The semantics of Java guarantee that the field will not be initialized until - // the field is referenced, - // and that any thread which accesses the field will see all of the writes - // resulting from initializing that field. - // http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html - private static class Holder { - private static LdifDataUtility INSTANCE = new LdifDataUtility(); - } - - private LdifDataUtility() { - } - - public static LdifDataUtility instance() { - return Holder.INSTANCE; - } - - /** - * Performs ldif file import - * - * @param connection - * Connection to LDAP server - * @param ldifFileName - * LDIF file - * @return The result code for the processing that was performed - */ - public ResultCode importLdifFile(LDAPConnection connection, String ldifFileName) { - LDIFReader ldifReader = createLdifReader(ldifFileName); - if (ldifReader == null) { - return ResultCode.LOCAL_ERROR; - } - try { - return importLdifFile(connection, ldifReader); - } finally { - disposeLdifReader(ldifReader); - } - } - - /** - * Performs ldif file conent import - * - * @param connection - * Connection to LDAP server - * @param ldifFileContent - * LDIF file - * @return The result code for the processing that was performed - */ - public ResultCode importLdifFileContent(LDAPConnection connection, String ldifFileContent) { - BufferedReader is = null; - LDIFReader ldifReader = null; - try { - is = new BufferedReader(new StringReader(ldifFileContent)); - ldifReader = new LDIFReader(is); - - return importLdifFile(connection, ldifReader); - } finally { - IOUtils.closeQuietly(is); - if (ldifReader != null) { - disposeLdifReader(ldifReader); - } - } - } - - /** - * Performs ldif file import - * - * @param connection - * Connection to LDAP server - * @param ldifReader - * LDIF reader - * @return The result code for the processing that was performed - */ - public ResultCode importLdifFile(LDAPConnection connection, LDIFReader ldifReader) { - // Attempt to process and apply the changes to the server - ResultCode resultCode = ResultCode.SUCCESS; - while (true) { - // Read the next change to process - LDIFChangeRecord ldifRecord = null; - try { - ldifRecord = ldifReader.readChangeRecord(true); - } catch (LDIFException le) { - LOG.error("Malformed ldif record", le); - if (!le.mayContinueReading()) { - resultCode = ResultCode.DECODING_ERROR; - break; - } - } catch (IOException ioe) { - LOG.error("I/O error encountered while reading a change record", ioe); - resultCode = ResultCode.LOCAL_ERROR; - break; - } - - // If the change record was null, then it means there are no more - // changes to be processed. - if (ldifRecord == null) { - break; - } - - // Apply the target change to the server. - try { - ldifRecord.processChange(connection); - } catch (LDAPException le) { - if (ResultCode.ENTRY_ALREADY_EXISTS.equals(le.getResultCode())) { - continue; - } - if (ldifRecord.getChangeType().equals(ChangeType.DELETE)) { - continue; - } - - LOG.error("Failed to inserting ldif record", le); - } - } - - return resultCode; - } - - /** - * Check if DS has at least one DN simular to specified in ldif file. - * - * @param connection - * Connection to LDAP server - * @param ldifFileName - * LDIF file - * @return true if server contains at least one DN simular to specified in ldif - * file. - */ - public boolean checkIfSerrverHasEntryFromLDIFFile(LDAPConnection connection, String ldifFileName) { - // Set up the LDIF reader that will be used to read the changes to apply - LDIFReader ldifReader = createLdifReader(ldifFileName); - if (ldifReader == null) { - return true; - } - - // Check all ldif entries - while (true) { - // Read the next change to process. - Entry entry = null; - try { - entry = ldifReader.readEntry(); - } catch (LDIFException le) { - LOG.error("Malformed ldif record", le); - if (!le.mayContinueReading()) { - return true; - } - } catch (IOException ioe) { - LOG.error("I/O error encountered while reading a change record", ioe); - return true; - } - - // If the change record was null, then it means there are no more - // changes to be processed. - if (entry == null) { - break; - } - - // Search entry in the server. - try { - SearchResult sr = connection.search(entry.getDN(), SearchScope.BASE, "objectClass=*"); - if ((sr != null) && (sr.getEntryCount() > 0)) { - return true; - } - } catch (LDAPException le) { - if (le.getResultCode() != ResultCode.NO_SUCH_OBJECT) { - LOG.error("Failed to search ldif record", le); - return true; - } - } - } - - disposeLdifReader(ldifReader); - - return false; - } - - /** - * Remove base entry with all sub entries - * - * @param connection - * Connection to LDAP server - * @param baseDN - * Base DN entry - * @return The result code for the processing that was performed. - */ - public ResultCode deleteEntryWithAllSubs(LDAPConnection connection, String baseDN) { - ResultCode resultCode = ResultCode.SUCCESS; - SearchResult searchResult = null; - try { - searchResult = connection.search(baseDN, SearchScope.SUB, "objectClass=*"); - if ((searchResult == null) || (searchResult.getEntryCount() == 0)) { - return ResultCode.LOCAL_ERROR; - } - } catch (LDAPSearchException le) { - LOG.error("Failed to search subordinate entries", le); - return ResultCode.LOCAL_ERROR; - } - - LinkedList dns = new LinkedList(); - for (SearchResultEntry entry : searchResult.getSearchEntries()) { - dns.add(entry.getDN()); - } - - ListIterator listIterator = dns.listIterator(dns.size()); - while (listIterator.hasPrevious()) { - try { - connection.delete(listIterator.previous()); - } catch (LDAPException le) { - LOG.error("Failed to delete entry", le); - resultCode = ResultCode.LOCAL_ERROR; - break; - } - } - - return resultCode; - } - - private LDIFReader createLdifReader(String ldifFileNamePath) { - // Set up the LDIF reader that will be used to read the changes to apply - File ldifFile = new File(ldifFileNamePath); - LDIFReader ldifReader; - try { - if (!ldifFile.exists()) { - return null; - } - ldifReader = new LDIFReader(ldifFile); - } catch (IOException ex) { - LOG.error("I/O error creating the LDIF reader", ex); - return null; - } - - return ldifReader; - } - - private void disposeLdifReader(LDIFReader ldifReader) { - if (ldifReader != null) { - try { - ldifReader.close(); - } catch (IOException ex) { - } - } - } - - public ResultCode validateLDIF(LDIFReader ldifReader, String dn) { - String baseDn = dn.toLowerCase(); - ResultCode resultCode = ResultCode.SUCCESS; - while (true) { - // Read the next change to process - LDIFChangeRecord ldifRecord = null; - try { - ldifRecord = ldifReader.readChangeRecord(true); - if (ldifRecord != null) { - if (StringHelper.isNotEmpty(baseDn)) { - if (!ldifRecord.getDN().toLowerCase().endsWith(baseDn)) { - resultCode = ResultCode.NOT_SUPPORTED; - break; - } - } - } - - } catch (LDIFException le) { - LOG.info("Malformed ldif record " + ldifRecord); - LOG.error("Malformed ldif record", le); - resultCode = ResultCode.DECODING_ERROR; - break; - } catch (IOException ioe) { - LOG.error("I/O error encountered while reading a change record", ioe); - resultCode = ResultCode.LOCAL_ERROR; - break; - } - - // If the change record was null, then it means there are no more - // changes to be processed. - if (ldifRecord == null) { - break; - } - } - - return resultCode; - } - - public List getAttributeResultEntryLDIF(LDAPConnection connection, List patterns, String baseDN) { - List searchResultEntryList = new ArrayList(); - try { - for (String pattern : patterns) { - String[] targetArray = new String[] {pattern}; - Filter inumFilter = Filter.createSubstringFilter("inum", null, targetArray, null); - Filter searchFilter = Filter.createORFilter(inumFilter); - SearchResultEntry sr = connection.searchForEntry(baseDN, SearchScope.SUB, searchFilter, null); - searchResultEntryList.add(sr); - } - - return searchResultEntryList; - } catch (LDAPException le) { - if (le.getResultCode() != ResultCode.NO_SUCH_OBJECT) { - LOG.error("Failed to search ldif record", le); - return null; - } - } - return null; - } - -} diff --git a/persistence-ldap/src/main/java/org/gluu/persist/ldap/operation/LdapOperationService.java b/persistence-ldap/src/main/java/org/gluu/persist/ldap/operation/LdapOperationService.java deleted file mode 100644 index 61b08b709..000000000 --- a/persistence-ldap/src/main/java/org/gluu/persist/ldap/operation/LdapOperationService.java +++ /dev/null @@ -1,126 +0,0 @@ -package org.gluu.persist.ldap.operation; - -import java.util.Collection; -import java.util.List; - -import org.gluu.persist.exception.operation.ConnectionException; -import org.gluu.persist.exception.operation.DuplicateEntryException; -import org.gluu.persist.exception.operation.SearchException; -import org.gluu.persist.ldap.impl.LdapBatchOperationWraper; -import org.gluu.persist.ldap.operation.impl.LdapConnectionProvider; -import org.gluu.persist.model.PagedResult; -import org.gluu.persist.model.SortOrder; -import org.gluu.persist.operation.PersistenceOperationService; - -import com.unboundid.ldap.sdk.Attribute; -import com.unboundid.ldap.sdk.Control; -import com.unboundid.ldap.sdk.Filter; -import com.unboundid.ldap.sdk.LDAPConnection; -import com.unboundid.ldap.sdk.LDAPConnectionPool; -import com.unboundid.ldap.sdk.LDAPException; -import com.unboundid.ldap.sdk.Modification; -import com.unboundid.ldap.sdk.SearchResult; -import com.unboundid.ldap.sdk.SearchResultEntry; -import com.unboundid.ldap.sdk.SearchScope; -import com.unboundid.ldif.LDIFChangeRecord; - -public interface LdapOperationService extends PersistenceOperationService { - - LdapConnectionProvider getConnectionProvider(); - - void setConnectionProvider(LdapConnectionProvider connectionProvider); - - LdapConnectionProvider getBindConnectionProvider(); - - void setBindConnectionProvider(LdapConnectionProvider bindConnectionProvider); - - LDAPConnectionPool getConnectionPool(); - - LDAPConnection getConnection() throws LDAPException; - - void releaseConnection(LDAPConnection connection); - - boolean authenticate(String bindDn, String password) throws ConnectionException; - - SearchResult search(String dn, Filter filter, SearchScope scope, LdapBatchOperationWraper batchOperationWraper, int start, - int searchLimit, int count, Control[] controls, String... attributes) throws SearchException; - - List searchSearchResultEntryList(String dn, Filter filter, SearchScope scope, int startIndex, - int count, int pageSize, String sortBy, SortOrder sortOrder, - PagedResult vlvResponse, String... attributes) throws Exception; - - SearchResult searchVirtualListView(String dn, Filter filter, SearchScope scope, int start, int count, - String sortBy, SortOrder sortOrder, PagedResult vlvResponse, String... attributes) - throws Exception; - - /** - * Lookup entry in the directory - * - * @param dn - * @param attributes - * @return SearchResultEntry - * @throws ConnectionException - */ - SearchResultEntry lookup(String dn, String... attributes) throws ConnectionException; - - /** - * Use this method to add new entry - * - * @param dn - * for entry - * @param atts - * attributes for entry - * @return true if successfully added - * @throws DuplicateEntryException - * @throws ConnectionException - * @throws DuplicateEntryException - * @throws ConnectionException - * @throws LDAPException - */ - boolean addEntry(String dn, Collection atts) throws DuplicateEntryException, ConnectionException; - - /** - * This method is used to update set of attributes for an entry - * - * @param dn - * @param modifications - * @return - * @throws ConnectionException - * @throws DuplicateEntryException - */ - boolean updateEntry(String dn, List modifications) throws DuplicateEntryException, ConnectionException; - - /** - * Delete entry from the directory - * - * @param dn - * @throws ConnectionException - */ - boolean delete(String dn) throws ConnectionException; - - /** - * Delete entry from the directory - * - * @param dn - * @return - * @throws ConnectionException - */ - boolean deleteRecursively(String dn) throws ConnectionException; - - boolean processChange(LDIFChangeRecord ldifRecord) throws LDAPException; - - int getSupportedLDAPVersion(); - - String getSubschemaSubentry(); - - boolean destroy(); - - boolean isBinaryAttribute(String attributeName); - - boolean isCertificateAttribute(String attributeName); - - String getCertificateAttributeName(String attributeName); - - List sortListByAttributes(List searchResultEntries, Class cls, boolean caseSensitive, boolean ascending, String... sortByAttributes); - -} diff --git a/persistence-ldap/src/main/java/org/gluu/persist/ldap/operation/impl/LdapAuthConnectionProvider.java b/persistence-ldap/src/main/java/org/gluu/persist/ldap/operation/impl/LdapAuthConnectionProvider.java deleted file mode 100644 index 75088d5d6..000000000 --- a/persistence-ldap/src/main/java/org/gluu/persist/ldap/operation/impl/LdapAuthConnectionProvider.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.gluu.persist.ldap.operation.impl; - -import java.util.Properties; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.unboundid.ldap.sdk.ResultCode; - -/** - * Authentication connection provider - * - * @author Yuriy Movchan Date: 12/29/2017 - */ -public class LdapAuthConnectionProvider extends LdapConnectionProvider { - - private static final Logger LOG = LoggerFactory.getLogger(LdapAuthConnectionProvider.class); - - public LdapAuthConnectionProvider(Properties connectionProperties) { - Properties bindConnectionProperties = prepareBindConnectionProperties(connectionProperties); - create(bindConnectionProperties); - if (ResultCode.INAPPROPRIATE_AUTHENTICATION.equals(getCreationResultCode())) { - LOG.warn("It's not possible to create authentication LDAP connection pool using anonymous bind. " - + "Attempting to create it using binDN/bindPassword"); - create(connectionProperties); - } - } - - private Properties prepareBindConnectionProperties(Properties connectionProperties) { - Properties bindProperties = (Properties) connectionProperties.clone(); - bindProperties.remove("bindDN"); - bindProperties.remove("bindPassword"); - - return bindProperties; - } - -} diff --git a/persistence-ldap/src/main/java/org/gluu/persist/ldap/operation/impl/LdapConnectionProvider.java b/persistence-ldap/src/main/java/org/gluu/persist/ldap/operation/impl/LdapConnectionProvider.java deleted file mode 100644 index 82b81cb79..000000000 --- a/persistence-ldap/src/main/java/org/gluu/persist/ldap/operation/impl/LdapConnectionProvider.java +++ /dev/null @@ -1,551 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.ldap.operation.impl; - -import java.security.GeneralSecurityException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Properties; - -import org.gluu.persist.exception.operation.ConfigurationException; -import org.gluu.persist.operation.auth.PasswordEncryptionMethod; -import org.gluu.util.ArrayHelper; -import org.gluu.util.StringHelper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.unboundid.ldap.sdk.BindRequest; -import com.unboundid.ldap.sdk.FailoverServerSet; -import com.unboundid.ldap.sdk.GetEntryLDAPConnectionPoolHealthCheck; -import com.unboundid.ldap.sdk.LDAPConnection; -import com.unboundid.ldap.sdk.LDAPConnectionOptions; -import com.unboundid.ldap.sdk.LDAPConnectionPool; -import com.unboundid.ldap.sdk.LDAPException; -import com.unboundid.ldap.sdk.ResultCode; -import com.unboundid.ldap.sdk.SimpleBindRequest; -import com.unboundid.util.ssl.SSLUtil; -import com.unboundid.util.ssl.TrustAllTrustManager; -import com.unboundid.util.ssl.TrustStoreTrustManager; - -/** - * @author Yuriy Movchan - */ -public class LdapConnectionProvider { - - private static final Logger LOG = LoggerFactory.getLogger(LdapConnectionProvider.class); - - private static final int DEFAULT_SUPPORTED_LDAP_VERSION = 2; - private static final String DEFAULT_SUBSCHEMA_SUBENTRY = "cn=schema"; - - private static final String[] SSL_PROTOCOLS = {"TLSv1.2", "TLSv1.1", "TLSv1", "SSLv3"}; - - private LDAPConnectionPool connectionPool; - private int creationResultCode; - - private int supportedLDAPVersion = DEFAULT_SUPPORTED_LDAP_VERSION; - private String subschemaSubentry = DEFAULT_SUBSCHEMA_SUBENTRY; - - private String[] servers; - private String[] addresses; - private int[] ports; - - private String bindDn; - private String bindPassword; - private boolean useSSL; - - private ArrayList additionalPasswordMethods; - private ArrayList binaryAttributes, certificateAttributes; - - private boolean supportsSubtreeDeleteRequestControl; - - - protected LdapConnectionProvider() { - } - - public LdapConnectionProvider(Properties props) { - create(props); - } - - protected void create(Properties props) { - try { - init(props); - } catch (LDAPException ex) { - creationResultCode = ex.getResultCode().intValue(); - - Properties clonedProperties = (Properties) props.clone(); - if (clonedProperties.getProperty("bindPassword") != null) { - clonedProperties.setProperty("bindPassword", "REDACTED"); - } - LOG.error("Failed to create connection pool with properties: " + clonedProperties, ex); - } catch (Exception ex) { - Properties clonedProperties = (Properties) props.clone(); - if (clonedProperties.getProperty("bindPassword") != null) { - clonedProperties.setProperty("bindPassword", "REDACTED"); - } - LOG.error("Failed to create connection pool with properties: " + clonedProperties, ex); - } - } - - /** - * This method is used to create LDAPConnectionPool - * - * @throws NumberFormatException - * @throws LDAPException - * @throws GeneralSecurityException - * @throws EncryptionException - * @throws EncryptionException - */ - protected void init(Properties props) throws NumberFormatException, LDAPException, GeneralSecurityException { - String serverProp = props.getProperty("servers"); - this.servers = serverProp.split(","); - this.addresses = new String[this.servers.length]; - this.ports = new int[this.servers.length]; - for (int i = 0; i < this.servers.length; i++) { - String str = this.servers[i]; - int idx = str.indexOf(":"); - if (idx == -1) { - throw new ConfigurationException("Ldap server settings should be in format server:port"); - } - this.addresses[i] = str.substring(0, idx).trim(); - this.ports[i] = Integer.parseInt(str.substring(str.indexOf(":") + 1, str.length())); - } - - BindRequest bindRequest = null; - if (StringHelper.isEmpty(props.getProperty("bindDN"))) { - this.bindDn = null; - this.bindPassword = null; - bindRequest = new SimpleBindRequest(); - } else { - this.bindDn = props.getProperty("bindDN"); - this.bindPassword = props.getProperty("bindPassword"); - bindRequest = new SimpleBindRequest(this.bindDn, this.bindPassword); - } - - LDAPConnectionOptions connectionOptions = new LDAPConnectionOptions(); - connectionOptions.setConnectTimeoutMillis(100 * 1000); - connectionOptions.setAutoReconnect(true); - - this.useSSL = Boolean.valueOf(props.getProperty("useSSL")).booleanValue(); - - SSLUtil sslUtil = null; - FailoverServerSet failoverSet; - if (this.useSSL) { - String sslTrustStoreFile = props.getProperty("ssl.trustStoreFile"); - String sslTrustStorePin = props.getProperty("ssl.trustStorePin"); - String sslTrustStoreFormat = props.getProperty("ssl.trustStoreFormat"); - - if (StringHelper.isEmpty(sslTrustStoreFile) && StringHelper.isEmpty(sslTrustStorePin)) { - sslUtil = new SSLUtil(new TrustAllTrustManager()); - } else { - TrustStoreTrustManager trustStoreTrustManager = new TrustStoreTrustManager(sslTrustStoreFile, sslTrustStorePin.toCharArray(), - sslTrustStoreFormat, true); - sslUtil = new SSLUtil(trustStoreTrustManager); - } - - failoverSet = new FailoverServerSet(this.addresses, this.ports, sslUtil.createSSLSocketFactory(SSL_PROTOCOLS[0]), connectionOptions); - } else { - failoverSet = new FailoverServerSet(this.addresses, this.ports, connectionOptions); - } - - int maxConnections = StringHelper.toInt(props.getProperty("maxconnections"), 10); - this.connectionPool = createConnectionPoolWithWaitImpl(props, failoverSet, bindRequest, connectionOptions, maxConnections, sslUtil); - if (this.connectionPool != null) { - this.connectionPool.setCreateIfNecessary(true); - String connectionMaxWaitTime = props.getProperty("connection.max-wait-time-millis"); - if (StringHelper.isNotEmpty(connectionMaxWaitTime)) { - this.connectionPool.setMaxWaitTimeMillis(Long.parseLong(connectionMaxWaitTime)); - } - String maxConnectionAge = props.getProperty("connection.max-age-time-millis"); - if (StringHelper.isNotEmpty(connectionMaxWaitTime)) { - this.connectionPool.setMaxConnectionAgeMillis(Long.parseLong(maxConnectionAge)); - } - boolean onCheckoutHealthCheckEnabled = StringHelper.toBoolean(props.getProperty("connection-pool.health-check.on-checkout.enabled"), false); - long healthCheckIntervalMillis = StringHelper.toLong(props.getProperty("connection-pool.health-check.interval-millis"), 0); - long healthCheckMaxResponsetimeMillis = StringHelper.toLong(props.getProperty("connection-pool.health-check.max-response-time-millis"), 0); - boolean backgroundHealthCheckEnabled = !onCheckoutHealthCheckEnabled && (healthCheckIntervalMillis > 0); - // Because otherwise it has no effect anyway - if (backgroundHealthCheckEnabled) { - this.connectionPool.setHealthCheckIntervalMillis(healthCheckIntervalMillis); - } - if (onCheckoutHealthCheckEnabled || backgroundHealthCheckEnabled) { - GetEntryLDAPConnectionPoolHealthCheck healthChecker = new GetEntryLDAPConnectionPoolHealthCheck(// entryDN (null means root DSE) - null, // maxResponseTime - healthCheckMaxResponsetimeMillis, // invokeOnCreate - false, // invokeOnCheckout - onCheckoutHealthCheckEnabled, // invokeOnRelease - false, // invokeForBackgroundChecks - backgroundHealthCheckEnabled, // invokeOnException - false); - - this.connectionPool.setHealthCheck(healthChecker); - } - } - - this.additionalPasswordMethods = new ArrayList(); - if (props.containsKey("additionalPasswordMethods")) { - String[] additionalPasswordMethodsArray = StringHelper.split(props.get("additionalPasswordMethods").toString(), ","); - for (String additionalPasswordMethod : additionalPasswordMethodsArray) { - PasswordEncryptionMethod passwordEncryptionMethod = PasswordEncryptionMethod.getMethod(additionalPasswordMethod); - if (passwordEncryptionMethod != null) { - this.additionalPasswordMethods.add(passwordEncryptionMethod); - } - } - } - LOG.debug("Adding support for password methods: " + this.additionalPasswordMethods); - - this.binaryAttributes = new ArrayList(); - if (props.containsKey("binaryAttributes")) { - String[] binaryAttrs = StringHelper.split(props.get("binaryAttributes").toString().toLowerCase(), ","); - this.binaryAttributes.addAll(Arrays.asList(binaryAttrs)); - } - LOG.debug("Using next binary attributes: " + this.binaryAttributes); - - this.certificateAttributes = new ArrayList(); - if (props.containsKey("certificateAttributes")) { - String[] binaryAttrs = StringHelper.split(props.get("certificateAttributes").toString().toLowerCase(), ","); - this.certificateAttributes.addAll(Arrays.asList(binaryAttrs)); - } - LOG.debug("Using next binary certificateAttributes: " + this.certificateAttributes); - - this.supportedLDAPVersion = determineSupportedLdapVersion(); - this.subschemaSubentry = determineSubschemaSubentry(); - this.supportsSubtreeDeleteRequestControl = supportsSubtreeDeleteRequestControl(); - this.creationResultCode = ResultCode.SUCCESS_INT_VALUE; - } - - private LDAPConnectionPool createConnectionPoolWithWaitImpl(Properties props, FailoverServerSet failoverSet, BindRequest bindRequest, - LDAPConnectionOptions connectionOptions, int maxConnections, SSLUtil sslUtil) throws LDAPException { - int connectionPoolMaxWaitTimeSeconds = StringHelper.toInt(props.getProperty("connection-pool-max-wait-time"), 30); - LOG.debug("Using LDAP connection pool timeout: '" + connectionPoolMaxWaitTimeSeconds + "'"); - - LDAPConnectionPool createdConnectionPool = null; - LDAPException lastException = null; - - int attempt = 0; - long currentTime = System.currentTimeMillis(); - long maxWaitTime = currentTime + connectionPoolMaxWaitTimeSeconds * 1000; - do { - attempt++; - if (attempt > 0) { - LOG.info("Attempting to create connection pool: " + attempt); - } - - try { - createdConnectionPool = createConnectionPoolImpl(failoverSet, bindRequest, connectionOptions, maxConnections, sslUtil); - break; - } catch (LDAPException ex) { - if (ex.getResultCode().intValue() != ResultCode.CONNECT_ERROR_INT_VALUE) { - throw ex; - } - lastException = ex; - } - - try { - Thread.sleep(5000); - } catch (InterruptedException ex) { - LOG.error("Exception happened in sleep", ex); - return null; - } - currentTime = System.currentTimeMillis(); - } while (maxWaitTime > currentTime); - - if ((createdConnectionPool == null) && (lastException != null)) { - throw lastException; - } - - return createdConnectionPool; - } - - private LDAPConnectionPool createConnectionPoolImpl(FailoverServerSet failoverSet, BindRequest bindRequest, - LDAPConnectionOptions connectionOptions, int maxConnections, SSLUtil sslUtil) throws LDAPException { - - LDAPConnectionPool createdConnectionPool; - try { - createdConnectionPool = new LDAPConnectionPool(failoverSet, bindRequest, maxConnections); - } catch (LDAPException ex) { - if (!this.useSSL) { - throw ex; - } - - // Error when LDAP server not supports specified encryption - if (ex.getResultCode() != ResultCode.SERVER_DOWN) { - throw ex; - } - - LOG.info("Attempting to use older SSL protocols", ex); - createdConnectionPool = createSSLConnectionPoolWithPreviousProtocols(sslUtil, bindRequest, connectionOptions, maxConnections); - if (createdConnectionPool == null) { - throw ex; - } - } - - return createdConnectionPool; - } - - private LDAPConnectionPool createSSLConnectionPoolWithPreviousProtocols(SSLUtil sslUtil, BindRequest bindRequest, - LDAPConnectionOptions connectionOptions, int maxConnections) throws LDAPException { - for (int i = 1; i < SSL_PROTOCOLS.length; i++) { - String protocol = SSL_PROTOCOLS[i]; - try { - FailoverServerSet failoverSet = new FailoverServerSet(this.addresses, this.ports, sslUtil.createSSLSocketFactory(protocol), - connectionOptions); - LDAPConnectionPool connectionPool = new LDAPConnectionPool(failoverSet, bindRequest, maxConnections); - - LOG.info("Server supports: '" + protocol + "'"); - return connectionPool; - } catch (GeneralSecurityException ex) { - LOG.debug("Server not supports: '" + protocol + "'", ex); - } catch (LDAPException ex) { - // Error when LDAP server not supports specified encryption - if (ex.getResultCode() != ResultCode.SERVER_DOWN) { - throw ex; - } - LOG.debug("Server not supports: '" + protocol + "'", ex); - } - } - - return null; - } - - private int determineSupportedLdapVersion() { - int resultSupportedLDAPVersion = LdapConnectionProvider.DEFAULT_SUPPORTED_LDAP_VERSION; - - boolean validConnection = isValidConnection(); - if (!validConnection) { - return resultSupportedLDAPVersion; - } - - try { - String[] supportedLDAPVersions = connectionPool.getRootDSE().getAttributeValues("supportedLDAPVersion"); - if (ArrayHelper.isEmpty(supportedLDAPVersions)) { - return resultSupportedLDAPVersion; - } - - for (String supportedLDAPVersion : supportedLDAPVersions) { - resultSupportedLDAPVersion = Math.max(resultSupportedLDAPVersion, Integer.parseInt(supportedLDAPVersion)); - } - } catch (Exception ex) { - LOG.error("Failed to determine supportedLDAPVersion", ex); - } - - return resultSupportedLDAPVersion; - } - - private String determineSubschemaSubentry() { - String resultSubschemaSubentry = LdapConnectionProvider.DEFAULT_SUBSCHEMA_SUBENTRY; - - boolean validConnection = isValidConnection(); - if (!validConnection) { - return resultSubschemaSubentry; - } - - try { - String subschemaSubentry = connectionPool.getRootDSE().getAttributeValue("subschemaSubentry"); - if (StringHelper.isEmpty(subschemaSubentry)) { - return resultSubschemaSubentry; - } - resultSubschemaSubentry = subschemaSubentry; - } catch (Exception ex) { - LOG.error("Failed to determine subschemaSubentry", ex); - } - - return resultSubschemaSubentry; - } - - private boolean supportsSubtreeDeleteRequestControl() { - boolean supportsSubtreeDeleteRequestControl = false; - - boolean validConnection = isValidConnection(); - if (!validConnection) { - return supportsSubtreeDeleteRequestControl; - } - - try { - supportsSubtreeDeleteRequestControl = connectionPool.getRootDSE() - .supportsControl(com.unboundid.ldap.sdk.controls.SubtreeDeleteRequestControl.SUBTREE_DELETE_REQUEST_OID); - } catch (Exception ex) { - LOG.error("Failed to determine if LDAP server supports Subtree Delete Request Control", ex); - } - - return supportsSubtreeDeleteRequestControl; - } - - private boolean isValidConnection() { - if (StringHelper.isEmptyString(bindDn) || StringHelper.isEmptyString(bindPassword)) { - return false; - } - - if (connectionPool == null) { - return false; - } - - return true; - } - - public int getSupportedLDAPVersion() { - return supportedLDAPVersion; - } - - public String getSubschemaSubentry() { - return subschemaSubentry; - } - - public boolean isSupportsSubtreeDeleteRequestControl() { - return supportsSubtreeDeleteRequestControl; - } - - /** - * This method is used to get LDAP connection from connectionPool if the - * connection is not available it will return new connection - * - * @return LDAPConnection from the connectionPool - * @throws LDAPException - */ - public LDAPConnection getConnection() throws LDAPException { - return connectionPool.getConnection(); - } - - /** - * Use this method to get connection pool instance; - * - * @return LDAPConnectionPool - * @throws LDAPException - * @throws NumberFormatException - */ - - /** - * Use this static method to release LDAPconnection to LDAPConnectionpool - * - * @param connection - */ - public void releaseConnection(LDAPConnection connection) { - connectionPool.releaseConnection(connection); - } - - /** - * This method to release back the connection after a exception occured - * - * @param connection - * @param ex - * (LDAPException) - */ - public void releaseConnection(LDAPConnection connection, LDAPException ex) { - connectionPool.releaseConnectionAfterException(connection, ex); - } - - /** - * This method is used to release back a connection that is no longer been used - * or fit to be used - * - * @param connection - */ - public void closeDefunctConnection(LDAPConnection connection) { - connectionPool.releaseDefunctConnection(connection); - } - - public LDAPConnectionPool getConnectionPool() { - return connectionPool; - } - - public void closeConnectionPool() { - connectionPool.close(); - } - - public boolean isConnected() { - if (connectionPool == null) { - return false; - } - - boolean isConnected = false; - try { - LDAPConnection connection = getConnection(); - try { - isConnected = connection.isConnected(); - } finally { - releaseConnection(connection); - } - } catch (LDAPException ex) { - } - - return isConnected; - } - - public int getCreationResultCode() { - return creationResultCode; - } - - public void setCreationResultCode(int creationResultCode) { - this.creationResultCode = creationResultCode; - } - - public boolean isCreated() { - return ResultCode.SUCCESS_INT_VALUE == this.creationResultCode; - } - - public String[] getServers() { - return servers; - } - - public String[] getAddresses() { - return addresses; - } - - public int[] getPorts() { - return ports; - } - - public String getBindDn() { - return bindDn; - } - - public String getBindPassword() { - return bindPassword; - } - - public boolean isUseSSL() { - return useSSL; - } - - public final ArrayList getAdditionalPasswordMethods() { - return additionalPasswordMethods; - } - - public ArrayList getBinaryAttributes() { - return binaryAttributes; - } - - public ArrayList getCertificateAttributes() { - return certificateAttributes; - } - - public boolean isBinaryAttribute(String attributeName) { - if (StringHelper.isEmpty(attributeName)) { - return false; - } - - return binaryAttributes.contains(attributeName.toLowerCase()); - } - - public boolean isCertificateAttribute(String attributeName) { - String realAttributeName = getCertificateAttributeName(attributeName); - - return certificateAttributes.contains(realAttributeName.toLowerCase()); - } - - public String getCertificateAttributeName(String attributeName) { - if (StringHelper.isEmpty(attributeName)) { - return attributeName; - } - - if (attributeName.endsWith(";binary")) { - return attributeName.substring(0, attributeName.length() - 7); - } - - return attributeName; - } - -} diff --git a/persistence-ldap/src/main/java/org/gluu/persist/ldap/operation/impl/LdapOperationsServiceImpl.java b/persistence-ldap/src/main/java/org/gluu/persist/ldap/operation/impl/LdapOperationsServiceImpl.java deleted file mode 100644 index e7b5c026d..000000000 --- a/persistence-ldap/src/main/java/org/gluu/persist/ldap/operation/impl/LdapOperationsServiceImpl.java +++ /dev/null @@ -1,1164 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.ldap.operation.impl; - -import java.io.Serializable; -import java.time.Duration; -import java.time.Instant; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.commons.lang.StringUtils; -import org.gluu.persist.exception.MappingException; -import org.gluu.persist.exception.operation.ConnectionException; -import org.gluu.persist.exception.operation.DuplicateEntryException; -import org.gluu.persist.exception.operation.SearchException; -import org.gluu.persist.ldap.exception.InvalidSimplePageControlException; -import org.gluu.persist.ldap.impl.LdapBatchOperationWraper; -import org.gluu.persist.ldap.operation.LdapOperationService; -import org.gluu.persist.ldap.operation.watch.OperationDurationUtil; -import org.gluu.persist.model.BatchOperation; -import org.gluu.persist.model.PagedResult; -import org.gluu.persist.model.SortOrder; -import org.gluu.persist.operation.auth.PasswordEncryptionHelper; -import org.gluu.persist.operation.auth.PasswordEncryptionMethod; -import org.gluu.util.ArrayHelper; -import org.gluu.util.Pair; -import org.gluu.util.StringHelper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.unboundid.asn1.ASN1OctetString; -import com.unboundid.ldap.sdk.Attribute; -import com.unboundid.ldap.sdk.BindResult; -import com.unboundid.ldap.sdk.Control; -import com.unboundid.ldap.sdk.DeleteRequest; -import com.unboundid.ldap.sdk.Filter; -import com.unboundid.ldap.sdk.LDAPConnection; -import com.unboundid.ldap.sdk.LDAPConnectionPool; -import com.unboundid.ldap.sdk.LDAPException; -import com.unboundid.ldap.sdk.LDAPResult; -import com.unboundid.ldap.sdk.LDAPSearchException; -import com.unboundid.ldap.sdk.Modification; -import com.unboundid.ldap.sdk.ModificationType; -import com.unboundid.ldap.sdk.ModifyRequest; -import com.unboundid.ldap.sdk.ResultCode; -import com.unboundid.ldap.sdk.SearchRequest; -import com.unboundid.ldap.sdk.SearchResult; -import com.unboundid.ldap.sdk.SearchResultEntry; -import com.unboundid.ldap.sdk.SearchResultReference; -import com.unboundid.ldap.sdk.SearchScope; -import com.unboundid.ldap.sdk.controls.ServerSideSortRequestControl; -import com.unboundid.ldap.sdk.controls.SimplePagedResultsControl; -import com.unboundid.ldap.sdk.controls.SortKey; -import com.unboundid.ldap.sdk.controls.SubtreeDeleteRequestControl; -import com.unboundid.ldap.sdk.controls.VirtualListViewRequestControl; -import com.unboundid.ldap.sdk.controls.VirtualListViewResponseControl; -import com.unboundid.ldap.sdk.schema.AttributeTypeDefinition; -import com.unboundid.ldif.LDIFChangeRecord; - -/** - * OperationsFacade is the base class that performs all the ldap operations - * using connectionpool - * - * @author Pankaj - * @author Yuriy Movchan - */ -public class LdapOperationsServiceImpl implements LdapOperationService { - - private static final Logger LOG = LoggerFactory.getLogger(LdapOperationsServiceImpl.class); - - public static final String DN = "dn"; - public static final String UID = "uid"; - public static final String SUCCESS = "success"; - public static final String USER_PASSWORD = "userPassword"; - public static final String OBJECT_CLASS = "objectClass"; - - private LdapConnectionProvider connectionProvider; - private LdapConnectionProvider bindConnectionProvider; - - private static Map> ATTRIBUTE_DATA_TYPES = new HashMap>(); - private static final Map> OID_SYNTAX_CLASS_MAPPING; - - static { - //Populates the mapping of syntaxes that will support comparison of attribute values. - //Only accounting for the most common and existing in Gluu Schema - OID_SYNTAX_CLASS_MAPPING = new HashMap>(); - //See RFC4517, section 3.3 - OID_SYNTAX_CLASS_MAPPING.put("1.3.6.1.4.1.1466.115.121.1.7", Boolean.class); - OID_SYNTAX_CLASS_MAPPING.put("1.3.6.1.4.1.1466.115.121.1.11", String.class); //Country String - OID_SYNTAX_CLASS_MAPPING.put("1.3.6.1.4.1.1466.115.121.1.15", String.class); //Directory String - OID_SYNTAX_CLASS_MAPPING.put("1.3.6.1.4.1.1466.115.121.1.12", String.class); //DN - OID_SYNTAX_CLASS_MAPPING.put("1.3.6.1.4.1.1466.115.121.1.22", String.class); //Facsimile - OID_SYNTAX_CLASS_MAPPING.put("1.3.6.1.4.1.1466.115.121.1.24", Date.class); //Generalized Time - OID_SYNTAX_CLASS_MAPPING.put("1.3.6.1.4.1.1466.115.121.1.26", String.class); //IA5 String (used in email) - OID_SYNTAX_CLASS_MAPPING.put("1.3.6.1.4.1.1466.115.121.1.27", Integer.class); - OID_SYNTAX_CLASS_MAPPING.put("1.3.6.1.4.1.1466.115.121.1.36", String.class); //Numeric string - OID_SYNTAX_CLASS_MAPPING.put("1.3.6.1.4.1.1466.115.121.1.41", String.class); //Postal address - OID_SYNTAX_CLASS_MAPPING.put("1.3.6.1.4.1.1466.115.121.1.50", String.class); //Telephone number - } - - @SuppressWarnings("unused") - private LdapOperationsServiceImpl() { - } - - public LdapOperationsServiceImpl(LdapConnectionProvider connectionProvider) { - this(connectionProvider, null); - populateAttributeDataTypesMapping(getSubschemaSubentry()); - } - - public LdapOperationsServiceImpl(LdapConnectionProvider connectionProvider, LdapConnectionProvider bindConnectionProvider) { - this.connectionProvider = connectionProvider; - this.bindConnectionProvider = bindConnectionProvider; - populateAttributeDataTypesMapping(getSubschemaSubentry()); - } - - /* - * (non-Javadoc) - * - * @see org.gluu.site.ldap.PlatformOperationFacade#getConnectionProvider() - */ - @Override - public LdapConnectionProvider getConnectionProvider() { - return connectionProvider; - } - - /* - * (non-Javadoc) - * - * @see - * org.gluu.site.ldap.PlatformOperationFacade#setConnectionProvider(org.gluu. - * site.ldap.LdapConnectionProvider) - */ - @Override - public void setConnectionProvider(LdapConnectionProvider connectionProvider) { - this.connectionProvider = connectionProvider; - } - - /* - * (non-Javadoc) - * - * @see org.gluu.site.ldap.PlatformOperationFacade#getBindConnectionProvider() - */ - @Override - public LdapConnectionProvider getBindConnectionProvider() { - return bindConnectionProvider; - } - - /* - * (non-Javadoc) - * - * @see - * org.gluu.site.ldap.PlatformOperationFacade#setBindConnectionProvider(org.gluu - * .site.ldap.LdapConnectionProvider) - */ - @Override - public void setBindConnectionProvider(LdapConnectionProvider bindConnectionProvider) { - this.bindConnectionProvider = bindConnectionProvider; - } - - /* - * (non-Javadoc) - * - * @see org.gluu.site.ldap.PlatformOperationFacade#getConnectionPool() - */ - @Override - public LDAPConnectionPool getConnectionPool() { - return connectionProvider.getConnectionPool(); - } - - /* - * (non-Javadoc) - * - * @see org.gluu.site.ldap.PlatformOperationFacade#getConnection() - */ - @Override - public LDAPConnection getConnection() throws LDAPException { - return connectionProvider.getConnection(); - } - - /* - * (non-Javadoc) - * - * @see - * org.gluu.site.ldap.PlatformOperationFacade#releaseConnection(com.unboundid. - * ldap.sdk.LDAPConnection) - */ - @Override - public void releaseConnection(LDAPConnection connection) { - connectionProvider.releaseConnection(connection); - } - - /* - * (non-Javadoc) - * - * @see - * org.gluu.site.ldap.PlatformOperationFacade#authenticate(java.lang.String, - * java.lang.String) - */ - @Override - public boolean authenticate(final String bindDn, final String password) throws ConnectionException { - try { - return authenticateImpl(bindDn, password); - } catch (LDAPException ex) { - throw new ConnectionException("Failed to authenticate dn", ex); - } - } - - private boolean authenticateImpl(final String bindDn, final String password) throws LDAPException, ConnectionException { - Instant startTime = OperationDurationUtil.instance().now(); - - boolean result = false; - - // Try to authenticate if the password was encrypted with additional mechanism - List additionalPasswordMethods = this.connectionProvider.getAdditionalPasswordMethods(); - if (!additionalPasswordMethods.isEmpty()) { - - SearchResultEntry searchResult = lookup(bindDn, USER_PASSWORD); - if (searchResult == null) { - throw new ConnectionException("Failed to find use by dn"); - } - - String storedUserPassword = searchResult.getAttribute(USER_PASSWORD).getValue(); - PasswordEncryptionMethod storedPasswordMethod = PasswordEncryptionHelper.findAlgorithm(storedUserPassword); - if (additionalPasswordMethods.contains(storedPasswordMethod)) { - LOG.debug("Authenticating '{}' using internal authentication mechanism '{}'", bindDn, storedPasswordMethod); - result = PasswordEncryptionHelper.compareCredentials(password, storedUserPassword); - } - } else { - if (this.bindConnectionProvider == null) { - result = authenticateConnectionPoolImpl(bindDn, password); - } else { - result = authenticateBindConnectionPoolImpl(bindDn, password); - } - } - - Duration duration = OperationDurationUtil.instance().duration(startTime); - OperationDurationUtil.instance().logDebug("LDAP operation: bind, duration: {}, dn: {}", duration, bindDn); - - return result; - } - - private boolean authenticateConnectionPoolImpl(final String bindDn, final String password) throws LDAPException, ConnectionException { - boolean loggedIn = false; - - if (bindDn == null) { - return loggedIn; - } - - boolean closeConnection = false; - LDAPConnection connection = connectionProvider.getConnection(); - try { - closeConnection = true; - BindResult r = connection.bind(bindDn, password); - if (r.getResultCode() == ResultCode.SUCCESS) { - loggedIn = true; - } - } finally { - connectionProvider.releaseConnection(connection); - // We can't use connection which binded as ordinary user - if (closeConnection) { - connectionProvider.closeDefunctConnection(connection); - } - } - - return loggedIn; - } - - private boolean authenticateBindConnectionPoolImpl(final String bindDn, final String password) throws LDAPException, ConnectionException { - if (bindDn == null) { - return false; - } - - LDAPConnection connection = bindConnectionProvider.getConnection(); - try { - BindResult r = connection.bind(bindDn, password); - return r.getResultCode() == ResultCode.SUCCESS; - } finally { - bindConnectionProvider.releaseConnection(connection); - } - } - - /* - * (non-Javadoc) - * - * @see org.gluu.site.ldap.PlatformOperationFacade#search(java.lang.String, - * com.unboundid.ldap.sdk.Filter, org.gluu.ldap.model.SearchScope, - * org.gluu.site.ldap.persistence.BatchOperation, int, int, int, - * com.unboundid.ldap.sdk.Control[], java.lang.String) - */ - @Override - public SearchResult search(String dn, Filter filter, SearchScope scope, LdapBatchOperationWraper batchOperationWraper, int start, - int searchLimit, int count, Control[] controls, String... attributes) throws SearchException { - Instant startTime = OperationDurationUtil.instance().now(); - - SearchResult result = searchImpl(dn, filter, scope, batchOperationWraper, start, searchLimit, count, controls, attributes); - - Duration duration = OperationDurationUtil.instance().duration(startTime); - OperationDurationUtil.instance().logDebug("LDAP operation: search, duration: {}, dn: {}, filter: {}, scope: {}, batchOperationWraper: {}, start: {}, searchLimit: {}, count: {}, controls: {}, attributes: {}", duration, dn, filter, scope, batchOperationWraper, start, searchLimit, count, controls, attributes); - - return result; - } - - private SearchResult searchImpl(String dn, Filter filter, SearchScope scope, LdapBatchOperationWraper batchOperationWraper, int start, - int searchLimit, int count, Control[] controls, String... attributes) throws SearchException { - SearchRequest searchRequest; - - BatchOperation ldapBatchOperation = null; - if (batchOperationWraper != null) { - ldapBatchOperation = (BatchOperation) batchOperationWraper.getBatchOperation(); - } - - if (LOG.isTraceEnabled()) { - // Find whole tree search. This can be very slow - if (StringHelper.equalsIgnoreCase(dn, "o=gluu")) { - LOG.trace("Search in whole LDAP tree", new Exception()); - } - } - - if (attributes == null) { - searchRequest = new SearchRequest(dn, scope, filter); - } else { - searchRequest = new SearchRequest(dn, scope, filter, attributes); - } - - boolean useSizeLimit = count > 0; - - if (useSizeLimit) { - // Use paged result to limit search - searchLimit = count; - } - - SearchResult searchResult = null; - List searchResultList = new ArrayList(); - List searchResultEntries = new ArrayList(); - List searchResultReferences = new ArrayList(); - - if ((searchLimit > 0) || (start > 0)) { - if (searchLimit == 0) { - // Default page size - searchLimit = 100; - } - - boolean collectSearchResult; - - LDAPConnection ldapConnection = null; - try { - ldapConnection = getConnectionPool().getConnection(); - ASN1OctetString cookie = null; - if (start > 0) { - try { - cookie = scrollSimplePagedResultsControl(ldapConnection, dn, filter, scope, controls, start); - } catch (InvalidSimplePageControlException ex) { - throw new LDAPSearchException(ex.getResultCode(), "Failed to scroll to specified start", ex); - } catch (LDAPException ex) { - throw new LDAPSearchException(ex.getResultCode(), "Failed to scroll to specified start", ex); - } - } - - do { - collectSearchResult = true; - searchRequest.setControls(new Control[] {new SimplePagedResultsControl(searchLimit, cookie)}); - setControls(searchRequest, controls); - searchResult = ldapConnection.search(searchRequest); - - if (ldapBatchOperation != null) { - collectSearchResult = ldapBatchOperation.collectSearchResult(searchResult.getEntryCount()); - } - if (collectSearchResult) { - searchResultList.add(searchResult); - searchResultEntries.addAll(searchResult.getSearchEntries()); - searchResultReferences.addAll(searchResult.getSearchReferences()); - } - - if (ldapBatchOperation != null) { - List entries = batchOperationWraper.createEntities(searchResult); - ldapBatchOperation.performAction(entries); - } - cookie = null; - try { - SimplePagedResultsControl c = SimplePagedResultsControl.get(searchResult); - if (c != null) { - cookie = c.getCookie(); - } - } catch (LDAPException ex) { - LOG.error("Error while accessing cookies" + ex.getMessage()); - } - - if (useSizeLimit) { - break; - } - } while ((cookie != null) && (cookie.getValueLength() > 0)); - } catch (LDAPException ex) { - throw new SearchException("Failed to scroll to specified start", ex, ex.getResultCode().intValue()); - } finally { - if (ldapConnection != null) { - getConnectionPool().releaseConnection(ldapConnection); - } - } - - if (!collectSearchResult) { - return new SearchResult(searchResult.getMessageID(), searchResult.getResultCode(), searchResult.getDiagnosticMessage(), - searchResult.getMatchedDN(), searchResult.getReferralURLs(), searchResultEntries, searchResultReferences, - searchResultEntries.size(), searchResultReferences.size(), searchResult.getResponseControls()); - } - - if (!searchResultList.isEmpty()) { - SearchResult searchResultTemp = searchResultList.get(0); - return new SearchResult(searchResultTemp.getMessageID(), searchResultTemp.getResultCode(), searchResultTemp.getDiagnosticMessage(), - searchResultTemp.getMatchedDN(), searchResultTemp.getReferralURLs(), searchResultEntries, searchResultReferences, - searchResultEntries.size(), searchResultReferences.size(), searchResultTemp.getResponseControls()); - } - } else { - setControls(searchRequest, controls); - try { - searchResult = getConnectionPool().search(searchRequest); - } catch (LDAPSearchException ex) { - throw new SearchException(ex.getMessage(), ex, ex.getResultCode().intValue()); - } - } - - return searchResult; - } - - private ASN1OctetString scrollSimplePagedResultsControl(LDAPConnection ldapConnection, String dn, Filter filter, SearchScope scope, - Control[] controls, int start) throws LDAPException, InvalidSimplePageControlException { - SearchRequest searchRequest = new SearchRequest(dn, scope, filter, "dn"); - - int currentStartIndex = start; - ASN1OctetString cookie = null; - do { - int pageSize = Math.min(currentStartIndex, 100); - searchRequest.setControls(new Control[] {new SimplePagedResultsControl(pageSize, cookie, true)}); - setControls(searchRequest, controls); - SearchResult searchResult = ldapConnection.search(searchRequest); - - currentStartIndex -= searchResult.getEntryCount(); - try { - SimplePagedResultsControl c = SimplePagedResultsControl.get(searchResult); - if (c != null) { - cookie = c.getCookie(); - } - } catch (LDAPException ex) { - LOG.error("Error while accessing cookie", ex); - throw new InvalidSimplePageControlException(ex.getResultCode(), "Error while accessing cookie"); - } - } while ((cookie != null) && (cookie.getValueLength() > 0) && (currentStartIndex > 0)); - - return cookie; - } - - /* - * (non-Javadoc) - * - * @see org.gluu.site.ldap.PlatformOperationFacade#searchSearchResult(java.lang. - * String, com.unboundid.ldap.sdk.Filter, org.gluu.ldap.model.SearchScope, int, - * int, int, java.lang.String, org.gluu.ldap.model.SortOrder, - * org.gluu.ldap.model.VirtualListViewResponse, java.lang.String) - */ - @Override - public List searchSearchResultEntryList(String dn, Filter filter, SearchScope scope, int startIndex, - int count, int pageSize, String sortBy, SortOrder sortOrder, - PagedResult vlvResponse, String... attributes) throws Exception { - Instant startTime = OperationDurationUtil.instance().now(); - - List result = searchSearchResultEntryListImpl(dn, filter, scope, startIndex, count, pageSize, sortBy, sortOrder, vlvResponse, attributes); - - Duration duration = OperationDurationUtil.instance().duration(startTime); - OperationDurationUtil.instance().logDebug("LDAP operation: search_result_list, duration: {}, dn: {}, filter: {}, scope: {}, startIndex: {}, count: {}, pageSize: {}, sortBy: {}, sortOrder: {}, vlvResponse: {}, attributes: {}", duration, dn, filter, scope, startIndex, count, pageSize, sortBy, sortOrder, vlvResponse, attributes); - - return result; - } - - private List searchSearchResultEntryListImpl(String dn, Filter filter, SearchScope scope, int start, int count, - int pageSize, String sortBy, SortOrder sortOrder, PagedResult vlvResponse, String... attributes) throws LDAPException, Exception { - //This method does not assume that count <= pageSize as occurs in SCIM, but it's more general - - //Why this? - if (StringHelper.equalsIgnoreCase(dn, "o=gluu")) { - (new Exception()).printStackTrace(); - } - - List searchEntries; - ASN1OctetString resumeCookie = null; - LDAPConnection conn = getConnection(); - SearchRequest searchRequest = new SearchRequest(dn, scope, filter, attributes); - - int totalResults = 0; - - do { - //Keep searching while we reach start index... - SearchResult searchResult = nextSearchResult(conn, searchRequest, pageSize, resumeCookie); - searchEntries = searchResult.getSearchEntries(); - totalResults += searchEntries.size(); - - resumeCookie = getSearchResultCookie(searchResult); - } while (totalResults < start && resumeCookie != null); - - List searchResultEntryList = new ArrayList(); - - if (totalResults > start) { - //Take the interesting ones, ie. skip [0, start) interval - int lowerBound = searchEntries.size() - (totalResults - start); - int upperBound = Math.min(searchEntries.size(), lowerBound + count); - searchResultEntryList.addAll(searchEntries.subList(lowerBound, upperBound)); - } - - //Continue adding results till reaching count if needed - while (resumeCookie != null && totalResults < count + start) { - SearchResult searchResult = nextSearchResult(conn, searchRequest, pageSize, resumeCookie); - searchEntries = searchResult.getSearchEntries(); - searchResultEntryList.addAll(searchEntries); - totalResults += searchEntries.size(); - - resumeCookie = getSearchResultCookie(searchResult); - } - - if (totalResults > count + start) { - //Remove the uninteresting tail - searchResultEntryList = searchResultEntryList.subList(0, count); - } - - //skip the rest and update the number of total results only - while (resumeCookie != null) { - SearchResult searchResult = nextSearchResult(conn, searchRequest, pageSize, resumeCookie); - searchEntries = searchResult.getSearchEntries(); - totalResults += searchEntries.size(); - - resumeCookie = getSearchResultCookie(searchResult); - } - - if (StringUtils.isNotEmpty(sortBy)) { - boolean ascending = sortOrder == null || sortOrder.equals(SortOrder.ASCENDING); - searchResultEntryList = sortListByAttributes(searchResultEntryList, SearchResultEntry.class, false, ascending, sortBy); - } - - // Get results info - vlvResponse.setEntriesCount(searchResultEntryList.size()); - vlvResponse.setTotalEntriesCount(totalResults); - vlvResponse.setStart(start); - - releaseConnection(conn); - return searchResultEntryList; - } - - private ASN1OctetString getSearchResultCookie(SearchResult searchResult) throws Exception { - SimplePagedResultsControl responseControl = SimplePagedResultsControl.get(searchResult); - return responseControl.moreResultsToReturn() ? responseControl.getCookie() : null; - } - - private SearchResult nextSearchResult(LDAPConnection connection, SearchRequest searchRequest, int pageSize, - ASN1OctetString resumeCookie) throws Exception { - - searchRequest.setControls(new SimplePagedResultsControl(pageSize, resumeCookie)); - SearchResult result = connection.search(searchRequest); - - if (!ResultCode.SUCCESS.equals(result.getResultCode())) { - String msgErr = "Search operation returned: " + result.getResultCode(); - LOG.error(msgErr); - throw new Exception(msgErr); - } - return result; - - } - - /* - * (non-Javadoc) - * - * @see - * org.gluu.site.ldap.PlatformOperationFacade#searchVirtualListView(java.lang. - * String, com.unboundid.ldap.sdk.Filter, org.gluu.ldap.model.SearchScope, int, - * int, java.lang.String, org.gluu.ldap.model.SortOrder, - * org.gluu.ldap.model.VirtualListViewResponse, java.lang.String) - */ - @Deprecated - public SearchResult searchVirtualListView(String dn, Filter filter, SearchScope scope, int start, int count, String sortBy, - SortOrder sortOrder, PagedResult vlvResponse, String... attributes) throws Exception { - Instant startTime = OperationDurationUtil.instance().now(); - - SearchResult result = searchVirtualListViewImpl(dn, filter, scope, start, count, sortBy, sortOrder, vlvResponse, attributes); - - Duration duration = OperationDurationUtil.instance().duration(startTime); - OperationDurationUtil.instance().logDebug("LDAP operation: search_virtual_list_view, duration: {}, dn: {}, filter: {}, scope: {}, start: {}, count: {}, sortBy: {}, sortOrder: {}, vlvResponse: {}, attributes: {}", duration, dn, filter, scope, start, count, sortBy, sortOrder, vlvResponse, attributes); - - return result; - } - - private SearchResult searchVirtualListViewImpl(String dn, Filter filter, SearchScope scope, int start, int count, String sortBy, - SortOrder sortOrder, PagedResult vlvResponse, String... attributes) throws LDAPSearchException, LDAPException { - if (StringHelper.equalsIgnoreCase(dn, "o=gluu")) { - (new Exception()).printStackTrace(); - } - - SearchRequest searchRequest; - - if (attributes == null) { - searchRequest = new SearchRequest(dn, scope, filter); - } else { - searchRequest = new SearchRequest(dn, scope, filter, attributes); - } - - // start and count should be "cleansed" before arriving here - int targetOffset = start; - int beforeCount = 0; - int afterCount = (count > 0) ? (count - 1) : 0; - int contentCount = 0; - - boolean reverseOrder = false; - if (sortOrder != null) { - reverseOrder = sortOrder.equals(SortOrder.DESCENDING) ? true : false; - } - - // Note that the VLV control always requires the server-side sort control. - searchRequest.setControls(new ServerSideSortRequestControl(new SortKey(sortBy, reverseOrder)), - new VirtualListViewRequestControl(targetOffset, beforeCount, afterCount, contentCount, null)); - - SearchResult searchResult = getConnectionPool().search(searchRequest); - - /* - * for (SearchResultEntry searchResultEntry : searchResult.getSearchEntries()) { - * log.info("##### searchResultEntry = " + searchResultEntry.toString()); } - */ - - // LDAPTestUtils.assertHasControl(searchResult, - // VirtualListViewResponseControl.VIRTUAL_LIST_VIEW_RESPONSE_OID); - - VirtualListViewResponseControl vlvResponseControl = VirtualListViewResponseControl.get(searchResult); - - // Get results info - vlvResponse.setEntriesCount(searchResult.getEntryCount()); - vlvResponse.setTotalEntriesCount(vlvResponseControl.getContentCount()); - vlvResponse.setStart(vlvResponseControl.getTargetPosition()); - - return searchResult; - } - - private void setControls(SearchRequest searchRequest, Control... controls) { - if (!ArrayHelper.isEmpty(controls)) { - Control[] newControls; - if (ArrayHelper.isEmpty(searchRequest.getControls())) { - newControls = controls; - } else { - newControls = ArrayHelper.arrayMerge(searchRequest.getControls(), controls); - } - - searchRequest.setControls(newControls); - } - } - - /* - * (non-Javadoc) - * - * @see org.gluu.site.ldap.PlatformOperationFacade#lookup(java.lang.String, - * java.lang.String) - */ - @Override - public SearchResultEntry lookup(String dn, String... attributes) throws ConnectionException { - Instant startTime = OperationDurationUtil.instance().now(); - - SearchResultEntry result = lookupImpl(dn, attributes); - - Duration duration = OperationDurationUtil.instance().duration(startTime); - OperationDurationUtil.instance().logDebug("LDAP operation: lookup, duration: {}, dn: {}, attributes: {}", duration, dn, attributes); - - return result; - } - - private SearchResultEntry lookupImpl(String dn, String... attributes) { - try { - if (attributes == null) { - return getConnectionPool().getEntry(dn); - } else { - return getConnectionPool().getEntry(dn, attributes); - } - } catch (Exception ex) { - throw new ConnectionException("Failed to lookup entry", ex); - } - } - - /* - * (non-Javadoc) - * - * @see org.gluu.site.ldap.PlatformOperationFacade#addEntry(java.lang.String, - * java.util.Collection) - */ - @Override - public boolean addEntry(String dn, Collection attributes) throws DuplicateEntryException, ConnectionException { - Instant startTime = OperationDurationUtil.instance().now(); - - boolean result = addEntryImpl(dn, attributes); - - Duration duration = OperationDurationUtil.instance().duration(startTime); - OperationDurationUtil.instance().logDebug("LDAP operation: add, duration: {}, dn: {}, attributes: {}", duration, dn, attributes); - - return result; - } - - private boolean addEntryImpl(String dn, Collection attributes) throws DuplicateEntryException { - try { - LDAPResult result = getConnectionPool().add(dn, attributes); - if (result.getResultCode().getName().equalsIgnoreCase(LdapOperationsServiceImpl.SUCCESS)) { - return true; - } - } catch (final LDAPException ex) { - int errorCode = ex.getResultCode().intValue(); - if (errorCode == ResultCode.ENTRY_ALREADY_EXISTS_INT_VALUE) { - throw new DuplicateEntryException(); - } - if (errorCode == ResultCode.INSUFFICIENT_ACCESS_RIGHTS_INT_VALUE) { - throw new ConnectionException("LDAP config error: insufficient access rights.", ex); - } - if (errorCode == ResultCode.TIME_LIMIT_EXCEEDED_INT_VALUE) { - throw new ConnectionException("LDAP Error: time limit exceeded", ex); - } - if (errorCode == ResultCode.OBJECT_CLASS_VIOLATION_INT_VALUE) { - throw new ConnectionException("LDAP config error: schema violation contact LDAP admin.", ex); - } - - throw new ConnectionException("Error adding entry to directory. LDAP error number " + errorCode, ex); - } - - return false; - } - - /* - * (non-Javadoc) - * - * @see org.gluu.site.ldap.PlatformOperationFacade#updateEntry(java.lang.String, - * java.util.Collection) - */ - @Deprecated - protected boolean updateEntry(String dn, Collection attrs) throws DuplicateEntryException, ConnectionException { - List mods = new ArrayList(); - - for (Attribute attribute : attrs) { - String attributeName = attribute.getName(); - String attributeValue = attribute.getValue(); - if (attributeName.equalsIgnoreCase(LdapOperationsServiceImpl.OBJECT_CLASS) - || attributeName.equalsIgnoreCase(LdapOperationsServiceImpl.DN) - || attributeName.equalsIgnoreCase(LdapOperationsServiceImpl.USER_PASSWORD)) { - continue; - } else { - if (attributeValue != null) { - mods.add(new Modification(ModificationType.REPLACE, attributeName, attributeValue)); - } - } - } - - return updateEntry(dn, mods); - } - - /* - * (non-Javadoc) - * - * @see org.gluu.site.ldap.PlatformOperationFacade#updateEntry(java.lang.String, - * java.util.List) - */ - @Override - public boolean updateEntry(String dn, List modifications) throws DuplicateEntryException, ConnectionException { - Instant startTime = OperationDurationUtil.instance().now(); - - boolean result = updateEntryImpl(dn, modifications); - - Duration duration = OperationDurationUtil.instance().duration(startTime); - OperationDurationUtil.instance().logDebug("LDAP operation: modify, duration: {}, dn: {}, modifications: {}", duration, dn, modifications); - - return result; - } - - private boolean updateEntryImpl(String dn, List modifications) throws DuplicateEntryException { - ModifyRequest modifyRequest = new ModifyRequest(dn, modifications); - return modifyEntry(modifyRequest); - } - - /** - * Use this method to add / replace / delete attribute from entry - * - * @param modifyRequest - * @return true if modification is successful - * @throws DuplicateEntryException - * @throws ConnectionException - */ - protected boolean modifyEntry(ModifyRequest modifyRequest) throws DuplicateEntryException, ConnectionException { - LDAPResult modifyResult = null; - try { - modifyResult = getConnectionPool().modify(modifyRequest); - return ResultCode.SUCCESS.equals(modifyResult.getResultCode()); - } catch (final LDAPException ex) { - int errorCode = ex.getResultCode().intValue(); - if (errorCode == ResultCode.INSUFFICIENT_ACCESS_RIGHTS_INT_VALUE) { - throw new ConnectionException("LDAP config error: insufficient access rights.", ex); - } - if (errorCode == ResultCode.TIME_LIMIT_EXCEEDED_INT_VALUE) { - throw new ConnectionException("LDAP Error: time limit exceeded", ex); - } - if (errorCode == ResultCode.OBJECT_CLASS_VIOLATION_INT_VALUE) { - throw new ConnectionException("LDAP config error: schema violation contact LDAP admin.", ex); - } - - throw new ConnectionException("Error updating entry in directory. LDAP error number " + errorCode, ex); - } - } - - /* - * (non-Javadoc) - * - * @see org.gluu.site.ldap.PlatformOperationFacade#delete(java.lang.String) - */ - @Override - public boolean delete(String dn) throws ConnectionException { - Instant startTime = OperationDurationUtil.instance().now(); - - boolean result = deleteImpl(dn); - - Duration duration = OperationDurationUtil.instance().duration(startTime); - OperationDurationUtil.instance().logDebug("LDAP operation: delete, duration: {}, dn: {}", duration, dn); - - return result; - } - - private boolean deleteImpl(String dn) { - try { - LDAPResult result = getConnectionPool().delete(dn); - - return ResultCode.SUCCESS.equals(result.getResultCode()); - } catch (Exception ex) { - throw new ConnectionException("Failed to delete entry", ex); - } - } - - /* - * (non-Javadoc) - * - * @see org.gluu.site.ldap.PlatformOperationFacade#deleteWithSubtree(java.lang. - * String) - */ - @Override - public boolean deleteRecursively(String dn) throws ConnectionException { - Instant startTime = OperationDurationUtil.instance().now(); - - boolean result = deleteRecursivelyImpl(dn); - - Duration duration = OperationDurationUtil.instance().duration(startTime); - OperationDurationUtil.instance().logDebug("LDAP operation: delete_tree, duration: {}, dn: {}", duration, dn); - - return result; - } - - protected boolean deleteRecursivelyImpl(String dn) { - try { - final DeleteRequest deleteRequest = new DeleteRequest(dn); - deleteRequest.addControl(new SubtreeDeleteRequestControl()); - LDAPResult result = getConnectionPool().delete(deleteRequest); - - return ResultCode.SUCCESS.equals(result.getResultCode()); - } catch (Exception ex) { - throw new ConnectionException("Failed to delete entry", ex); - } - } - - /* - * (non-Javadoc) - * - * @see - * org.gluu.site.ldap.PlatformOperationFacade#processChange(com.unboundid.ldif. - * LDIFChangeRecord) - */ - @Override - public boolean processChange(LDIFChangeRecord ldifRecord) throws LDAPException { - LDAPConnection connection = getConnection(); - try { - LDAPResult ldapResult = ldifRecord.processChange(connection); - - return ResultCode.SUCCESS.equals(ldapResult.getResultCode()); - } finally { - releaseConnection(connection); - } - } - - /* - * (non-Javadoc) - * - * @see org.gluu.site.ldap.PlatformOperationFacade#getSupportedLDAPVersion() - */ - @Override - public int getSupportedLDAPVersion() { - return this.connectionProvider.getSupportedLDAPVersion(); - } - - /* - * (non-Javadoc) - * - * @see org.gluu.site.ldap.PlatformOperationFacade#getSubschemaSubentry() - */ - @Override - public String getSubschemaSubentry() { - return this.connectionProvider.getSubschemaSubentry(); - } - - /* - * (non-Javadoc) - * - * @see org.gluu.site.ldap.PlatformOperationFacade#destroy() - */ - @Override - public boolean destroy() { - boolean result = true; - - if (connectionProvider != null) { - try { - connectionProvider.closeConnectionPool(); - } catch (Exception ex) { - LOG.error("Failed to close connection pool correctly"); - result = false; - } - } - - if (bindConnectionProvider != null) { - try { - bindConnectionProvider.closeConnectionPool(); - } catch (Exception ex) { - LOG.error("Failed to close bind connection pool correctly"); - result = false; - } - } - - return result; - } - - /* - * (non-Javadoc) - * - * @see org.gluu.site.ldap.PlatformOperationFacade#isBinaryAttribute(java.lang. - * String) - */ - @Override - public boolean isBinaryAttribute(String attributeName) { - return this.connectionProvider.isBinaryAttribute(attributeName); - } - - /* - * (non-Javadoc) - * - * @see - * org.gluu.site.ldap.PlatformOperationFacade#isCertificateAttribute(java.lang. - * String) - */ - @Override - public boolean isCertificateAttribute(String attributeName) { - return this.connectionProvider.isCertificateAttribute(attributeName); - } - - /* - * (non-Javadoc) - * - * @see - * org.gluu.site.ldap.PlatformOperationFacade#getCertificateAttributeName(java. - * lang.String) - */ - @Override - public String getCertificateAttributeName(String attributeName) { - return this.connectionProvider.getCertificateAttributeName(attributeName); - } - - @Override - public List sortListByAttributes(List searchResultEntries, Class cls, boolean caseSensitive, - boolean ascending, String... sortByAttributes) { - // Check input parameters - if (searchResultEntries == null) { - throw new MappingException("Entries list to sort is null"); - } - - if (searchResultEntries.size() == 0) { - return searchResultEntries; - } - - SearchResultEntryComparator comparator = new SearchResultEntryComparator(sortByAttributes, caseSensitive, ascending); - - //The following line does not work because of type erasure - //T array[]=(T[])searchResultEntries.toArray(); - - //Converting the list to an array gets rid of unmodifiable list problem, see issue #68 - T[] dummyArr = (T[]) java.lang.reflect.Array.newInstance(cls, 0); - T[] array = searchResultEntries.toArray(dummyArr); - Arrays.sort(array, comparator); - return Arrays.asList(array); - - } - - private void populateAttributeDataTypesMapping(String schemaEntryDn) { - - try { - if (ATTRIBUTE_DATA_TYPES.size() == 0) { - //schemaEntryDn="ou=schema"; - SearchResultEntry entry = lookup(schemaEntryDn, "attributeTypes"); - Attribute attrAttributeTypes = entry.getAttribute("attributeTypes"); - - Map> tmpMap = new HashMap>(); - - for (String strAttributeType : attrAttributeTypes.getValues()) { - AttributeTypeDefinition attrTypeDef = new AttributeTypeDefinition(strAttributeType); - String[] names = attrTypeDef.getNames(); - - if (names != null) { - for (String name : names) { - tmpMap.put(name, new Pair(attrTypeDef.getBaseSyntaxOID(), attrTypeDef.getSuperiorType())); - } - } - } - - //Fill missing values - for (String name : tmpMap.keySet()) { - Pair currPair = tmpMap.get(name); - String sup = currPair.getSecond(); - - if (currPair.getFirst() == null && sup != null) { //No OID syntax? - //Try to lookup superior type - Pair pair = tmpMap.get(sup); - if (pair != null) { - currPair.setFirst(pair.getFirst()); - } - } - } - - //Populate map of attribute names vs. Java classes - for (String name : tmpMap.keySet()) { - String syntaxOID = tmpMap.get(name).getFirst(); - - if (syntaxOID != null) { - Class cls = OID_SYNTAX_CLASS_MAPPING.get(syntaxOID); - if (cls != null) { - ATTRIBUTE_DATA_TYPES.put(name, cls); - } - } - } - } - } catch (Exception e) { - LOG.error(e.getMessage(), e); - } - - } - - - private static final class SearchResultEntryComparator implements Comparator, Serializable { - - private static final long serialVersionUID = 574848841116711467L; - private String[] sortByAttributes; - private boolean caseSensitive; - private boolean ascending; - - private SearchResultEntryComparator(String[] sortByAttributes, boolean caseSensitive, boolean ascending) { - this.sortByAttributes = sortByAttributes; - this.caseSensitive = caseSensitive; - this.ascending = ascending; - } - - public int compare(T entry1, T entry2) { - - int result = 0; - - if (entry1 == null) { - if (entry2 == null) { - result = 0; - } else { - result = -1; - } - } else { - if (entry2 == null) { - result = 1; - } else { - for (String currSortByAttribute : sortByAttributes) { - result = compare(entry1, entry2, currSortByAttribute); - if (result != 0) { - break; - } - } - } - } - - if (!ascending) { - result *= -1; - } - - return result; - - } - - //This comparison assumes a default sort order of "ascending" - public int compare(T entry1, T entry2, String attributeName) { - - int result = 0; - try { - - if (entry1 instanceof SearchResultEntry) { - - SearchResultEntry resultEntry1 = (SearchResultEntry) entry1; - SearchResultEntry resultEntry2 = (SearchResultEntry) entry2; - - //Obtain a string representation first and do nulls treatments - String value1 = resultEntry1.getAttributeValue(attributeName); - String value2 = resultEntry2.getAttributeValue(attributeName); - - if (value1 == null) { - if (value2 == null) { - result = 0; - } else { - result = -1; - } - } else { - if (value2 == null) { - result = 1; - } else { - Class cls = ATTRIBUTE_DATA_TYPES.get(attributeName); - - if (cls != null) { - if (cls.equals(String.class)) { - if (caseSensitive) { - result = value1.compareTo(value2); - } else { - result = value1.toLowerCase().compareTo(value2.toLowerCase()); - } - } else - if (cls.equals(Integer.class)) { - result = resultEntry1.getAttributeValueAsInteger(attributeName) - .compareTo(resultEntry2.getAttributeValueAsInteger(attributeName)); - } else - if (cls.equals(Boolean.class)) { - result = resultEntry1.getAttributeValueAsBoolean(attributeName) - .compareTo(resultEntry2.getAttributeValueAsBoolean(attributeName)); - } else - if (cls.equals(Date.class)) { - result = resultEntry1.getAttributeValueAsDate(attributeName) - .compareTo(resultEntry2.getAttributeValueAsDate(attributeName)); - } - } - } - } - } - } catch (Exception e) { - LOG.error("Error occurred when comparing entries with SearchResultEntryComparator"); - LOG.error(e.getMessage(), e); - } - return result; - - } - - } - - @Override - public boolean isConnected() { - return connectionProvider.isConnected(); - } - -} - diff --git a/persistence-ldap/src/main/java/org/gluu/persist/ldap/operation/watch/OperationDurationUtil.java b/persistence-ldap/src/main/java/org/gluu/persist/ldap/operation/watch/OperationDurationUtil.java deleted file mode 100644 index 7444cb8bf..000000000 --- a/persistence-ldap/src/main/java/org/gluu/persist/ldap/operation/watch/OperationDurationUtil.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.gluu.persist.ldap.operation.watch; - -import org.gluu.persist.watch.DurationUtil; - -/** - * Simple LDAP operation duration calculator helper - * - * @author Yuriy Movchan Date: 04/08/2019 - */ -public class OperationDurationUtil extends DurationUtil { - - private static OperationDurationUtil instance = new OperationDurationUtil(); - - public static DurationUtil instance() { - return instance; - } - - public void logDebug(String format, Object... arguments) { - if (log.isDebugEnabled()) { - log.debug(format, arguments); - } - } - -} diff --git a/persistence-model/pom.xml b/persistence-model/pom.xml deleted file mode 100644 index bc968d4c5..000000000 --- a/persistence-model/pom.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - 4.0.0 - oxcore-persistence-model - jar - persistence-model - - - org.gluu - oxcore - 4.0.0-SNAPSHOT - - - - - org.gluu - oxcore-persistence-annotation - ${project.version} - - - ${project.groupId} - oxcore-util - ${project.version} - - - - \ No newline at end of file diff --git a/persistence-model/src/main/java/org/gluu/persist/model/base/BaseEntry.java b/persistence-model/src/main/java/org/gluu/persist/model/base/BaseEntry.java deleted file mode 100644 index cf732e044..000000000 --- a/persistence-model/src/main/java/org/gluu/persist/model/base/BaseEntry.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.model.base; - -import org.gluu.persist.annotation.DN; - -/** - * Provides DN attribute - * - * @author Yuriy Movchan Date: 10.07.2010 - */ -public class BaseEntry { - - @DN - private String dn; - - public BaseEntry() { - } - - public BaseEntry(String dn) { - super(); - this.dn = dn; - } - - public String getDn() { - return dn; - } - - public void setDn(String dn) { - this.dn = dn; - } - - public String getBaseDn() { - return dn; - } - - public void setBaseDn(String dn) { - this.dn = dn; - } - - @Override - public String toString() { - return String.format("BaseEntry [dn=%s]", dn); - } - -} diff --git a/persistence-model/src/main/java/org/gluu/persist/model/base/CustomAttribute.java b/persistence-model/src/main/java/org/gluu/persist/model/base/CustomAttribute.java deleted file mode 100644 index a066bd4c2..000000000 --- a/persistence-model/src/main/java/org/gluu/persist/model/base/CustomAttribute.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.model.base; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -/** - * @author Javier Rojas Date: 12.5.2011 - * @author Yuriy Movchan Date: 04/08/2014 -*/ -public class CustomAttribute implements Serializable, Comparable { - - private static final long serialVersionUID = 1468450094325306154L; - - private String name; - private List values; - - public CustomAttribute() { - } - - public CustomAttribute(String name) { - this.name = name; - } - - public CustomAttribute(String name, String value) { - this.name = name; - setValue(value); - } - - public CustomAttribute(String name, List values) { - this.name = name; - this.values = values; - } - - public String getValue() { - if (this.values == null) { - return null; - } - - if (this.values.size() > 0) { - return String.valueOf(this.values.get(0)); - } - - return null; - } - - public void setValue(String value) { - this.values = new ArrayList(); - this.values.add(value); - } - - public List getValues() { - return values; - } - - public void setValues(List values) { - this.values = values; - } - - public final String getName() { - return name; - } - - public final void setName(String name) { - this.name = name; - } - - public String getDisplayValue() { - if (values == null) { - return ""; - } - - if (values.size() == 1) { - return values.get(0); - } - - StringBuilder sb = new StringBuilder(values.get(0)); - for (int i = 1; i < values.size(); i++) { - sb.append(", ").append(values.get(i)); - } - - return sb.toString(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - CustomAttribute that = (CustomAttribute) o; - - if (name != null ? !name.equals(that.name) : that.name != null) { - return false; - } - - return true; - } - - @Override - public int hashCode() { - return name != null ? name.hashCode() : 0; - } - - @Override - public String toString() { - return String.format("Attribute [name=%s, values=%s]", name, values); - } - - public int compareTo(CustomAttribute o) { - return name.compareTo(o.name); - } -} diff --git a/persistence-model/src/main/java/org/gluu/persist/model/base/CustomEntry.java b/persistence-model/src/main/java/org/gluu/persist/model/base/CustomEntry.java deleted file mode 100644 index df1c7a21c..000000000 --- a/persistence-model/src/main/java/org/gluu/persist/model/base/CustomEntry.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.model.base; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -import org.gluu.persist.annotation.AttributesList; -import org.gluu.persist.annotation.CustomObjectClass; -import org.gluu.persist.annotation.DataEntry; -import org.gluu.persist.annotation.ObjectClass; -import org.gluu.util.StringHelper; - -/** - * @author Yuriy Movchan Date: 04/08/2014 - */ -@DataEntry -public class CustomEntry extends BaseEntry implements Serializable { - - private static final long serialVersionUID = -7686468010219068788L; - - @AttributesList(name = "name", value = "values", sortByName = true) - private List customAttributes = new ArrayList(); - - @CustomObjectClass - private String[] customObjectClasses; - - public List getCustomAttributes() { - return customAttributes; - } - - public String getCustomAttributeValue(String attributeName) { - if (customAttributes == null) { - return null; - } - - for (CustomAttribute customAttribute : customAttributes) { - if (StringHelper.equalsIgnoreCase(attributeName, customAttribute.getName())) { - return customAttribute.getValue(); - } - } - - return null; - } - - public void setCustomAttributes(List customAttributes) { - this.customAttributes = customAttributes; - } - - public String[] getCustomObjectClasses() { - return customObjectClasses; - } - - public void setCustomObjectClasses(String[] customObjectClasses) { - this.customObjectClasses = customObjectClasses; - } - -} diff --git a/persistence-model/src/main/java/org/gluu/persist/model/base/CustomObjectAttribute.java b/persistence-model/src/main/java/org/gluu/persist/model/base/CustomObjectAttribute.java deleted file mode 100644 index e7b39b33c..000000000 --- a/persistence-model/src/main/java/org/gluu/persist/model/base/CustomObjectAttribute.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.model.base; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -/** - * @author Yuriy Movchan Date: 09/16/2019 -*/ -public class CustomObjectAttribute implements Serializable, Comparable { - - private static final long serialVersionUID = -1238450094325306154L; - - private String name; - private boolean multiValued; - private List values; - - public CustomObjectAttribute() { - } - - public CustomObjectAttribute(String name) { - this.name = name; - } - - public CustomObjectAttribute(String name, Object value) { - this.name = name; - setValue(value); - this.multiValued = false; - } - - public CustomObjectAttribute(String name, List values) { - this.name = name; - setValues(values); - } - - public Object getValue() { - if (this.values == null) { - return null; - } - - if (this.values.size() > 0) { - return this.values.get(0); - } - - return null; - } - - public void setValue(Object value) { - this.values = new ArrayList(); - this.values.add(value); - this.multiValued = false; - } - - public List getValues() { - return values; - } - - public void setValues(List values) { - this.values = values; - this.multiValued = (values != null) && (values.size() > 1); - } - - public final String getName() { - return name; - } - - public final void setName(String name) { - this.name = name; - } - - public boolean isMultiValued() { - return multiValued; - } - - public void setMultiValued(boolean multiValued) { - this.multiValued = multiValued; - } - - public String getDisplayValue() { - if (values == null) { - return ""; - } - - if (values.size() == 1) { - return values.get(0).toString(); - } - - StringBuilder sb = new StringBuilder(values.get(0).toString()); - for (int i = 1; i < values.size(); i++) { - sb.append(", ").append(values.get(i).toString()); - } - - return sb.toString(); - } - - private String toStringValue() { - if (values == null) { - return ""; - } - - if (values.size() == 1) { - if (multiValued) { - return "[" + values.get(0).toString() + "]"; - } - return values.get(0).toString(); - } - - StringBuilder sb = new StringBuilder("["); - for (int i = 0; i < values.size(); i++) { - if (i > 0) { - sb.append(", "); - } - sb.append(values.get(i).toString()); - } - sb.append("]"); - - return sb.toString(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - CustomObjectAttribute that = (CustomObjectAttribute) o; - - if (name != null ? !name.equals(that.name) : that.name != null) { - return false; - } - - return true; - } - - @Override - public int hashCode() { - return name != null ? name.hashCode() : 0; - } - - @Override - public String toString() { - return String.format("Attribute [name=%s, multiValued=%s, value=%s]", name, multiValued, toStringValue()); - } - - public int compareTo(CustomObjectAttribute o) { - return name.compareTo(o.name); - } -} diff --git a/persistence-model/src/main/java/org/gluu/persist/model/base/Deletable.java b/persistence-model/src/main/java/org/gluu/persist/model/base/Deletable.java deleted file mode 100644 index befa8435c..000000000 --- a/persistence-model/src/main/java/org/gluu/persist/model/base/Deletable.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.gluu.persist.model.base; - -/** - * @author Yuriy Zabrovarnyy - */ -public interface Deletable { - boolean isDeletable(); -} diff --git a/persistence-model/src/main/java/org/gluu/persist/model/base/DeletableEntity.java b/persistence-model/src/main/java/org/gluu/persist/model/base/DeletableEntity.java deleted file mode 100644 index 2a649c99b..000000000 --- a/persistence-model/src/main/java/org/gluu/persist/model/base/DeletableEntity.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.gluu.persist.model.base; - -import org.gluu.persist.annotation.AttributeName; -import org.gluu.persist.annotation.DataEntry; - -import java.util.Date; - -/** - * @author Yuriy Zabrovarnyy - */ -@DataEntry -public class DeletableEntity extends BaseEntry implements Deletable { - - @AttributeName(name = "oxAuthExpiration") - private Date expirationDate; - @AttributeName(name = "exp") - private Date newExpirationDate; - @AttributeName(name = "del") - private boolean deletable = true; - - @Override - public boolean isDeletable() { - return deletable; - } - - public void setDeletable(boolean deletable) { - this.deletable = deletable; - } - - public Date getExpirationDate() { - return expirationDate; - } - - public void setExpirationDate(Date expirationDate) { - this.expirationDate = expirationDate; - } - - public Date getNewExpirationDate() { - return newExpirationDate; - } - - public void setNewExpirationDate(Date newExpirationDate) { - this.newExpirationDate = newExpirationDate; - } - - public boolean canDelete() { - return canDelete(new Date()); - } - - public boolean canDelete(Date now) { - Date exp = expirationDate != null ? expirationDate : newExpirationDate; - return deletable && (exp == null || exp.before(now)); - } - - @Override - public String toString() { - Date exp = expirationDate != null ? expirationDate : newExpirationDate; - return "DeletableEntity{" + - "expirationDate=" + exp + - ", deletable=" + deletable + - "} " + super.toString(); - } -} diff --git a/persistence-model/src/main/java/org/gluu/persist/model/base/DummyEntry.java b/persistence-model/src/main/java/org/gluu/persist/model/base/DummyEntry.java deleted file mode 100644 index 7b16abb4b..000000000 --- a/persistence-model/src/main/java/org/gluu/persist/model/base/DummyEntry.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.model.base; - -import java.io.Serializable; - -import org.gluu.persist.annotation.DataEntry; - -/** - * Dummy entry - * - * @author Yuriy Movchan Date: 07.13.2011 - */ -@DataEntry -public class DummyEntry extends BaseEntry implements Serializable { - - private static final long serialVersionUID = -1111582184398161100L; - -} diff --git a/persistence-model/src/main/java/org/gluu/persist/model/base/Entry.java b/persistence-model/src/main/java/org/gluu/persist/model/base/Entry.java deleted file mode 100644 index 1fb35dcea..000000000 --- a/persistence-model/src/main/java/org/gluu/persist/model/base/Entry.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.model.base; - -import java.io.Serializable; - -import org.gluu.persist.annotation.DN; - -/** - * Provides DN attribute - * - * @author Yuriy Movchan Date: 07/10/2010 - */ -public class Entry implements Serializable, Cloneable { - - private static final long serialVersionUID = 6602706707181973761L; - - @DN - private String dn; - - public Entry() { - } - - public Entry(String dn) { - super(); - this.dn = dn; - } - - public String getDn() { - return dn; - } - - public void setDn(String dn) { - this.dn = dn; - } - - public String getBaseDn() { - return dn; - } - - public void setBaseDn(String dn) { - this.dn = dn; - } - - @Override - public String toString() { - return String.format("Entry [dn=%s]", dn); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((dn == null) ? 0 : dn.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - Entry other = (Entry) obj; - if (dn == null) { - if (other.dn != null) { - return false; - } - } else if (!dn.equals(other.dn)) { - return false; - } - - return true; - } - -} diff --git a/persistence-model/src/main/java/org/gluu/persist/model/base/GluuBoolean.java b/persistence-model/src/main/java/org/gluu/persist/model/base/GluuBoolean.java deleted file mode 100644 index 7d971306c..000000000 --- a/persistence-model/src/main/java/org/gluu/persist/model/base/GluuBoolean.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.model.base; - -import java.util.HashMap; -import java.util.Map; - -import org.gluu.persist.annotation.AttributeEnum; - -/** - * Boolean value - * - * @author Yuriy Movchan Date: 11.20.2010 - */ - -@Deprecated // We need ot remove true/false from it at -public enum GluuBoolean implements AttributeEnum { - - DISABLED(false, "disabled", "Disabled"), ENABLED(true, "enabled", "Enabled"), FALSE(false, "false", "False"), TRUE(true, "true", "True"), - INACTIVE(false, "inactive", "Inactive"), ACTIVE(true, "active", "Active"); - - private boolean booleanValue; - private String value; - private String displayName; - - private static Map MAP_BY_VALUES = new HashMap(); - - static { - for (GluuBoolean enumType : values()) { - MAP_BY_VALUES.put(enumType.getValue(), enumType); - } - } - - GluuBoolean(boolean booleanValue, String value, String displayName) { - this.booleanValue = booleanValue; - this.value = value; - this.displayName = displayName; - } - - public String getValue() { - return value; - } - - public boolean isBooleanValue() { - return booleanValue; - } - - public static GluuBoolean getByValue(String value) { - return MAP_BY_VALUES.get(value); - } - - public String getDisplayName() { - return displayName; - } - - public Enum resolveByValue(String value) { - return getByValue(value); - } - - @Override - public String toString() { - return value; - } - -} diff --git a/persistence-model/src/main/java/org/gluu/persist/model/base/GluuDummyEntry.java b/persistence-model/src/main/java/org/gluu/persist/model/base/GluuDummyEntry.java deleted file mode 100644 index 14f42905d..000000000 --- a/persistence-model/src/main/java/org/gluu/persist/model/base/GluuDummyEntry.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.model.base; - -import java.io.Serializable; - -import org.gluu.persist.annotation.DataEntry; - -/** - * Person with custom attributes - * - * @author Yuriy Movchan Date: 07.13.2011 - */ -@DataEntry -public class GluuDummyEntry extends Entry implements Serializable { - - private static final long serialVersionUID = -1111582184398161100L; - -} diff --git a/persistence-model/src/main/java/org/gluu/persist/model/base/InumEntry.java b/persistence-model/src/main/java/org/gluu/persist/model/base/InumEntry.java deleted file mode 100644 index 524ac93bb..000000000 --- a/persistence-model/src/main/java/org/gluu/persist/model/base/InumEntry.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.model.base; - -import org.gluu.persist.annotation.AttributeName; -import org.gluu.persist.annotation.DataEntry; -import org.gluu.persist.annotation.ObjectClass; - -/** - * Provides global inum search ability. - * - * @author Oleksiy Tataryn - */ -@DataEntry -@ObjectClass -public class InumEntry extends Entry { - - @AttributeName(ignoreDuringUpdate = true) - private String inum; - - /** - * @param inum - * the inum to set - */ - public void setInum(String inum) { - this.inum = inum; - } - - /** - * @return the inum - */ - public String getInum() { - return inum; - } - - @Override - public String toString() { - return String.format("Entry [dn=%s, inum=%s]", getDn(), getInum()); - } - -} diff --git a/persistence-model/src/main/java/org/gluu/persist/model/base/SimpleBranch.java b/persistence-model/src/main/java/org/gluu/persist/model/base/SimpleBranch.java deleted file mode 100644 index 5d2b14124..000000000 --- a/persistence-model/src/main/java/org/gluu/persist/model/base/SimpleBranch.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.model.base; - -import java.io.Serializable; - -import org.gluu.persist.annotation.AttributeName; -import org.gluu.persist.annotation.DataEntry; -import org.gluu.persist.annotation.ObjectClass; - -/** - * Model for simple branch - * - * @author Yuriy Movchan Date: 11.01.2010 - */ -@DataEntry -@ObjectClass(value = "organizationalUnit") -public class SimpleBranch extends BaseEntry implements Serializable { - - private static final long serialVersionUID = -1311006812730222719L; - - @AttributeName(name = "ou") - private String organizationalUnitName; - - public SimpleBranch() { - } - - public SimpleBranch(String dn) { - setDn(dn); - } - - public SimpleBranch(String dn, String organizationalUnitName) { - this(dn); - this.organizationalUnitName = organizationalUnitName; - } - - public String getOrganizationalUnitName() { - return organizationalUnitName; - } - - public void setOrganizationalUnitName(String organizationalUnitName) { - this.organizationalUnitName = organizationalUnitName; - } - - @Override - public String toString() { - return String.format("SimpleBranch [organizationalUnitName=%s, toString()=%s]", organizationalUnitName, super.toString()); - } - -} diff --git a/persistence-model/src/main/java/org/gluu/persist/model/base/SimpleUser.java b/persistence-model/src/main/java/org/gluu/persist/model/base/SimpleUser.java deleted file mode 100644 index 8391220c3..000000000 --- a/persistence-model/src/main/java/org/gluu/persist/model/base/SimpleUser.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2014, Gluu - */ - -package org.gluu.persist.model.base; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -import org.gluu.persist.annotation.AttributeName; -import org.gluu.persist.annotation.AttributesList; -import org.gluu.persist.annotation.CustomObjectClass; -import org.gluu.persist.annotation.DN; -import org.gluu.persist.annotation.DataEntry; -import org.gluu.persist.annotation.ObjectClass; -import org.gluu.util.StringHelper; - -/** - * @author Javier Rojas Blum Date: 11.25.2011 - */ -@DataEntry -@ObjectClass -public class SimpleUser implements Serializable { - - private static final long serialVersionUID = -1634191420188575733L; - - @DN - private String dn; - @AttributeName(name = "uid") - private String userId; - - @AttributeName(name = "oxAuthPersistentJWT") - private String[] oxAuthPersistentJwt; - - @AttributesList(name = "name", value = "values", sortByName = true) - protected List customAttributes = new ArrayList(); - - @CustomObjectClass - private String[] customObjectClasses; - - public String getDn() { - return dn; - } - - public void setDn(String dn) { - this.dn = dn; - } - - public String getUserId() { - return userId; - } - - public void setUserId(String userId) { - this.userId = userId; - } - - public String[] getOxAuthPersistentJwt() { - return oxAuthPersistentJwt; - } - - public void setOxAuthPersistentJwt(String[] oxAuthPersistentJwt) { - this.oxAuthPersistentJwt = oxAuthPersistentJwt; - } - - public List getCustomAttributes() { - return customAttributes; - } - - public void setCustomAttributes(List customAttributes) { - this.customAttributes = customAttributes; - } - - public String getAttribute(String ldapAttribute) { - String attribute = null; - if (ldapAttribute != null && !ldapAttribute.isEmpty()) { - for (CustomAttribute customAttribute : customAttributes) { - if (customAttribute.getName().equals(ldapAttribute)) { - attribute = customAttribute.getValue(); - break; - } - } - } - - return attribute; - } - - public List getAttributeValues(String ldapAttribute) { - List values = null; - if (ldapAttribute != null && !ldapAttribute.isEmpty()) { - for (CustomAttribute customAttribute : customAttributes) { - if (StringHelper.equalsIgnoreCase(customAttribute.getName(), ldapAttribute)) { - values = customAttribute.getValues(); - break; - } - } - } - - return values; - } - - public String[] getCustomObjectClasses() { - return customObjectClasses; - } - - public void setCustomObjectClasses(String[] customObjectClasses) { - this.customObjectClasses = customObjectClasses; - } - -} diff --git a/persistence-standalone/src/main/java/org/gluu/persist/service/StandalonePersistanceFactoryService.java b/persistence-standalone/src/main/java/org/gluu/persist/service/StandalonePersistanceFactoryService.java deleted file mode 100644 index 7cf456a0e..000000000 --- a/persistence-standalone/src/main/java/org/gluu/persist/service/StandalonePersistanceFactoryService.java +++ /dev/null @@ -1,88 +0,0 @@ -package org.gluu.persist.service; - -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Set; - -import org.gluu.persist.PersistenceEntryManagerFactory; -import org.gluu.persist.exception.PropertyNotFoundException; -import org.gluu.persist.exception.operation.ConfigurationException; -import org.gluu.persist.model.PersistenceConfiguration; -import org.gluu.persist.reflect.util.ReflectHelper; - -/** - * Factory which creates Persistence Entry Manager - * - * @author Yuriy Movchan Date: 05/10/2019 - * @param - */ -public class StandalonePersistanceFactoryService extends PersistanceFactoryService { - - private HashMap persistenceEntryManagerFactoryNames; - private HashMap, PersistenceEntryManagerFactory> persistenceEntryManagerFactoryTypes; - - @Override - public PersistenceEntryManagerFactory getPersistenceEntryManagerFactory(PersistenceConfiguration persistenceConfiguration) { - return getPersistenceEntryManagerFactory(persistenceConfiguration.getEntryManagerFactoryType()); - } - - @Override - public PersistenceEntryManagerFactory getPersistenceEntryManagerFactory(Class persistenceEntryManagerFactoryClass) { - if (this.persistenceEntryManagerFactoryTypes == null) { - initPersistenceManagerMaps(); - } - - PersistenceEntryManagerFactory persistenceEntryManagerFactory = this.persistenceEntryManagerFactoryTypes - .get(persistenceEntryManagerFactoryClass); - - return persistenceEntryManagerFactory; - } - - @Override - public PersistenceEntryManagerFactory getPersistenceEntryManagerFactory(String persistenceType) { - if (this.persistenceEntryManagerFactoryNames == null) { - initPersistenceManagerMaps(); - } - - PersistenceEntryManagerFactory persistenceEntryManagerFactory = this.persistenceEntryManagerFactoryNames.get(persistenceType); - - return persistenceEntryManagerFactory; - } - - private void initPersistenceManagerMaps() { - this.persistenceEntryManagerFactoryNames = new HashMap(); - this.persistenceEntryManagerFactoryTypes = new HashMap, PersistenceEntryManagerFactory>(); - - org.reflections.Reflections reflections = new org.reflections.Reflections(new org.reflections.util.ConfigurationBuilder() - .setUrls(org.reflections.util.ClasspathHelper.forPackage("org.gluu.persist")) - .setScanners(new org.reflections.scanners.SubTypesScanner())); - Set> classes = reflections.getSubTypesOf(PersistenceEntryManagerFactory.class); - - getLog().info("Found '{}' PersistenceEntryManagerFactory", classes.size()); - - List> classesList = new ArrayList>(classes); - for (Class clazz : classesList) { - getLog().info("Found PersistenceEntryManagerFactory '{}'", clazz); - PersistenceEntryManagerFactory persistenceEntryManagerFactory = createPersistenceEntryManagerFactoryImpl(clazz); - persistenceEntryManagerFactoryNames.put(persistenceEntryManagerFactory.getPersistenceType(), persistenceEntryManagerFactory); - persistenceEntryManagerFactoryTypes.put(clazz, persistenceEntryManagerFactory); - } - } - - private PersistenceEntryManagerFactory createPersistenceEntryManagerFactoryImpl(Class persistenceEntryManagerFactoryClass) { - PersistenceEntryManagerFactory persistenceEntryManagerFactory; - try { - persistenceEntryManagerFactory = ReflectHelper.createObjectByDefaultConstructor(persistenceEntryManagerFactoryClass); - persistenceEntryManagerFactory.initStandalone(this); - } catch (PropertyNotFoundException | IllegalArgumentException | InstantiationException | IllegalAccessException - | InvocationTargetException e) { - throw new ConfigurationException( - String.format("Failed to create PersistenceEntryManagerFactory by type '%s'!", persistenceEntryManagerFactoryClass)); - } - - return persistenceEntryManagerFactory; - } - -} diff --git a/persistence-standalone/src/test/java/org/gluu/persist/service/test/.gitignore b/persistence-standalone/src/test/java/org/gluu/persist/service/test/.gitignore deleted file mode 100644 index eabb0d0d1..000000000 --- a/persistence-standalone/src/test/java/org/gluu/persist/service/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/manual/ diff --git a/pom.xml b/pom.xml index e208e10ac..9f119a30b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,9 +5,9 @@ org.gluu oxcore pom - 4.0.0-SNAPSHOT + 4.5.6-SNAPSHOT oxCore - http://ox.gluu.org + https://www.gluu.org ${maven.min-version} @@ -17,44 +17,8 @@ UTF-8 3.0.3 - - 3.7.0.Final - - 3.1.1.Final - 4.5.17-gluu.Final - - 2.2.19 - 2.2.19 - 2.2.1-b04 - 2.2.1-b05 - - 2.9.9 - 2.9.10 - 2.11.2 - 1.7.26 - - 27.1-jre - - - central - Maven Repository Switchboard - default - http://repo1.maven.org/maven2 - - - repository.jboss.org - JBoss Repository - http://repository.jboss.org/nexus/content/groups/public-jboss/ - - - gluu - Gluu repository - http://ox.gluu.org/maven - - - https://github.com/GluuFederation/oxCore scm:git:git://github.com/GluuFederation/oxCore.git @@ -63,303 +27,43 @@ oxUtil - persistence-filter - persistence-model - persistence-core - persistence-ldap - persistence-annotation - persistence-couchbase - persistence-hybrid - persistence-cdi - persistence-standalone - persistence-ldap-sample - persistence-couchbase-sample oxModel + core-cache + core-document-store + core-standalone oxSaml + oxJsfUtil + core-java-ext + core-cdi + core-timer-weld + security-extension-cdi + exception-extension-cdi + core-script oxService server - oxJsfUtil oxRadius demo-cdi + doc - - - - - org.jboss.weld - weld-core-parent - ${weld.version} + org.gluu + gluu-core-bom + 4.5.6-SNAPSHOT import pom - javax.el - el-api - ${uel-api.version} - provided - - - org.glassfish.web - el-impl - ${uel-impl.version} - - - com.sun.faces - jsf-api - ${jsf-api.version} - - - org.glassfish - javax.faces - ${jsf-impl.version} - - - - javax.persistence - persistence-api - 1.0.2 - - - - - org.richfaces - richfaces - ${richfaces.version} - - - org.richfaces - richfaces-core - ${richfaces.version} - - - - net.jodah - expiringmap - 0.5.9 - - - - commons-io - commons-io - 2.6 - - - commons-codec - commons-codec - 1.12 - - - org.apache.commons - commons-exec - 1.3 - - - commons-configuration - commons-configuration - 1.10 - - - org.apache.commons - commons-text - 1.6 - - - commons-beanutils - commons-beanutils - 1.9.3 - - - - - org.apache.logging.log4j - log4j-api - ${log4j.version} - - - org.apache.logging.log4j - log4j-1.2-api - ${log4j.version} - - - org.apache.logging.log4j - log4j-core - ${log4j.version} - - - - org.slf4j - slf4j-api - ${slf4j.version} - - - org.slf4j - slf4j-log4j12 - ${slf4j.version} - test - - - org.apache.logging.log4j - log4j-slf4j-impl - ${log4j.version} - - - org.slf4j - slf4j-simple - ${slf4j.version} - - - - net.sf.ehcache - ehcache-core - 2.10.6 - - - - org.reflections - reflections - 0.9.11 - - - - - com.fasterxml.jackson.core - jackson-annotations - ${jackson.version} - - - com.fasterxml.jackson.core - jackson-core - ${jackson.version} - - - com.fasterxml.jackson.core - jackson-databind - ${jackson.databind.version} - - - - - org.python - jython-standalone - 2.7.1 - - - - - org.jboss.resteasy - resteasy-jaxrs - ${resteasy.version} - - - org.jboss.resteasy - resteasy-jackson2-provider - ${resteasy.version} - - - - - javax.mail - mail - 1.4.7 - - - - - net.spy - spymemcached - 2.12.3 - - - redis.clients - jedis - 2.10.2 - - - - - org.apache.httpcomponents - httpcore - 4.4.11 - - - org.apache.httpcomponents - httpclient - 4.5.8 - - - - - org.apache.ws.security - wss4j - 1.6.19 - - - - - com.unboundid - unboundid-ldapsdk - 4.0.7 - - - - - com.couchbase.client - java-client - 2.7.9 - - - - - io.dropwizard.metrics - metrics-core - 4.0.5 - - - - - org.eclipse.jetty - jetty-deploy - 9.4.19.v20190610 - provided - - - - - org.testng - testng - 6.9.4 - test - - - - - org.testng - testng - 6.9.4 - test - - - - com.beust - jcommander - 1.72 - test - - - - javax.servlet - javax.servlet-api - 3.1.0 - provided + jakarta.xml.bind + jakarta.xml.bind-api + 2.3.3 - org.quartz-scheduler - quartz - 2.3.1 + javax.annotation + javax.annotation-api + 1.3.2 @@ -455,6 +159,13 @@ false + + org.apache.maven.plugins + maven-javadoc-plugin + + false + + @@ -475,4 +186,27 @@ + + + + mavencentral + maven central + https://repo1.maven.org/maven2 + + + bouncycastle + Bouncy Castle + https://repo2.maven.org/maven2/org/bouncycastle + + + gluu + Gluu project repository + https://maven.gluu.org/maven + + + shib-release + shib release + https://build.shibboleth.net/nexus/content/groups/public + + \ No newline at end of file diff --git a/persistence-cdi/pom.xml b/security-extension-cdi/pom.xml similarity index 61% rename from persistence-cdi/pom.xml rename to security-extension-cdi/pom.xml index b549c67c0..b78634acb 100644 --- a/persistence-cdi/pom.xml +++ b/security-extension-cdi/pom.xml @@ -2,14 +2,13 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.gluu - oxcore-persistence-cdi - Persistence CDI services + security-extension-cdi + Reusable CDI security extension org.gluu oxcore - 4.0.0-SNAPSHOT + 4.5.6-SNAPSHOT @@ -31,33 +30,42 @@ + - org.gluu - oxcore-persistence-core - ${project.version} - - - org.gluu - oxcore-persistence-annotation - ${project.version} + ${project.groupId} + oxcore-jsf-util - - org.gluu - oxcore-persistence-ldap - ${project.version} - + org.slf4j - slf4j-simple + slf4j-api + provided - + javax.enterprise cdi-api provided + + org.jboss.weld + weld-core-impl + provided + + + + + javax.servlet + javax.servlet-api + provided + + + javax.ws.rs + javax.ws.rs-api + + \ No newline at end of file diff --git a/security-extension-cdi/src/main/java/org/gluu/oxtrust/auth/uma/annotations/UmaSecure.java b/security-extension-cdi/src/main/java/org/gluu/oxtrust/auth/uma/annotations/UmaSecure.java new file mode 100644 index 000000000..3501e6580 --- /dev/null +++ b/security-extension-cdi/src/main/java/org/gluu/oxtrust/auth/uma/annotations/UmaSecure.java @@ -0,0 +1,33 @@ +/* + * oxTrust is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2018, Gluu + */ +package org.gluu.oxtrust.auth.uma.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.interceptor.InterceptorBinding; + +/** + * Marks a class as a UMA scope resource. + * + * Provides service to protect Rest service endpoints with UMA scope. + * + * @author Dmitry Ognyannikov + */ +@Inherited +@InterceptorBinding +@Target(value = {ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Deprecated +public @interface UmaSecure { + /** + * UMA scopes as single string + */ + String scope() default ""; +} diff --git a/security-extension-cdi/src/main/java/org/gluu/oxtrust/auth/uma/annotations/UmaSecureInterceptor.java b/security-extension-cdi/src/main/java/org/gluu/oxtrust/auth/uma/annotations/UmaSecureInterceptor.java new file mode 100644 index 000000000..297435295 --- /dev/null +++ b/security-extension-cdi/src/main/java/org/gluu/oxtrust/auth/uma/annotations/UmaSecureInterceptor.java @@ -0,0 +1,109 @@ +/* + * oxTrust is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2018, Gluu + */ +package org.gluu.oxtrust.auth.uma.annotations; + +import java.lang.annotation.Annotation; +import java.util.HashMap; +import java.util.Map; + +import javax.annotation.Priority; +import javax.inject.Inject; +import javax.interceptor.AroundInvoke; +import javax.interceptor.Interceptor; +import javax.interceptor.InvocationContext; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.core.Response; + +import org.gluu.service.el.ExpressionEvaluator; +import org.gluu.service.security.InterceptSecure; +import org.gluu.service.security.Secure; +import org.gluu.service.security.SecureVariable; +import org.gluu.service.security.SecurityEvaluationException; +import org.gluu.service.security.SecurityExtension; +import org.slf4j.Logger; + +/** + * Provides service to protect Rest service endpoints with UMA scope. + * + * @author Dmitry Ognyannikov + */ +@Interceptor +@UmaSecure +@Priority(Interceptor.Priority.PLATFORM_AFTER) +@Deprecated +public class UmaSecureInterceptor { + + @Inject + private Logger log; + + @Inject + private SecurityExtension securityExtension; + + @Inject + private ExpressionEvaluator expressionEvaluator; + + @AroundInvoke + public Object invoke(InvocationContext ctx) throws Exception { + HttpServletResponse response = null; + Object[] parameters = ctx.getParameters(); + + log.trace("REST method call security check. " + ctx.getMethod().getName() + "()"); + + for (Object parameter : parameters) { + if (parameter instanceof HttpServletResponse) + response = (HttpServletResponse)parameter; + } + + InterceptSecure is = securityExtension.getInterceptSecure(ctx.getMethod()); + + // SecurityChecking restrictions + Secure[] constraints = (is == null) ? new Secure[0] : is.value(); + + // Getting the parameter values + Map secureVars = computeParameterValues(ctx); + + for (Secure constraint : constraints) { + Boolean expressionValue = expressionEvaluator.evaluateValueExpression(constraint.value(), Boolean.class, secureVars); + + if ((expressionValue == null) || !expressionValue) { + log.debug("Method: '{}' constrain '{}' evaluation is null or false!", ctx.getMethod(), constraint); + throw new SecurityEvaluationException(); + } + } + + try { + // the method call + return ctx.proceed(); + } catch (Exception e) { + log.error("Error calling ctx.proceed in UmaSecureInterceptor"); + // REST call error report + if (response != null) { + try { response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "INTERNAL SERVER ERROR"); } catch (Exception ex) {} + } else if (Response.class.isAssignableFrom(ctx.getMethod().getReturnType())) { + return Response.serverError().entity("INTERNAL SERVER ERROR").build(); + } + + return null; + } + } + + private Map computeParameterValues(InvocationContext ctx) { + Annotation[][] parametersAnnotations = ctx.getMethod().getParameterAnnotations(); + Map secureVariables = new HashMap(); + for (int i = 0; i < parametersAnnotations.length; i++) { + Annotation[] parameterAnnotations = parametersAnnotations[i]; + for (Annotation parameterAnnotation : parameterAnnotations) { + if (SecureVariable.class.isAssignableFrom(parameterAnnotation.annotationType())) { + SecureVariable secureVariable = (SecureVariable) parameterAnnotation; + Object paramValue = ctx.getParameters()[i]; + secureVariables.put(secureVariable.value(), paramValue); + } + } + } + + return secureVariables; + } +} diff --git a/oxService/src/main/java/org/gluu/service/security/InterceptSecure.java b/security-extension-cdi/src/main/java/org/gluu/service/security/InterceptSecure.java similarity index 100% rename from oxService/src/main/java/org/gluu/service/security/InterceptSecure.java rename to security-extension-cdi/src/main/java/org/gluu/service/security/InterceptSecure.java diff --git a/oxService/src/main/java/org/gluu/service/security/Secure.java b/security-extension-cdi/src/main/java/org/gluu/service/security/Secure.java similarity index 100% rename from oxService/src/main/java/org/gluu/service/security/Secure.java rename to security-extension-cdi/src/main/java/org/gluu/service/security/Secure.java diff --git a/oxService/src/main/java/org/gluu/service/security/SecureVariable.java b/security-extension-cdi/src/main/java/org/gluu/service/security/SecureVariable.java similarity index 100% rename from oxService/src/main/java/org/gluu/service/security/SecureVariable.java rename to security-extension-cdi/src/main/java/org/gluu/service/security/SecureVariable.java diff --git a/oxService/src/main/java/org/gluu/service/security/SecurityEvaluationException.java b/security-extension-cdi/src/main/java/org/gluu/service/security/SecurityEvaluationException.java similarity index 88% rename from oxService/src/main/java/org/gluu/service/security/SecurityEvaluationException.java rename to security-extension-cdi/src/main/java/org/gluu/service/security/SecurityEvaluationException.java index e740e056c..9184e7f9b 100644 --- a/oxService/src/main/java/org/gluu/service/security/SecurityEvaluationException.java +++ b/security-extension-cdi/src/main/java/org/gluu/service/security/SecurityEvaluationException.java @@ -1,11 +1,8 @@ package org.gluu.service.security; -import javax.ejb.ApplicationException; - /** * @author Yuriy Movchan Date: 05/22/2017 */ -@ApplicationException(rollback = true) public class SecurityEvaluationException extends RuntimeException { private static final long serialVersionUID = 7115786700134354355L; diff --git a/oxService/src/main/java/org/gluu/service/security/SecurityExtension.java b/security-extension-cdi/src/main/java/org/gluu/service/security/SecurityExtension.java similarity index 100% rename from oxService/src/main/java/org/gluu/service/security/SecurityExtension.java rename to security-extension-cdi/src/main/java/org/gluu/service/security/SecurityExtension.java diff --git a/oxService/src/main/java/org/gluu/service/security/SecurityInterceptor.java b/security-extension-cdi/src/main/java/org/gluu/service/security/SecurityInterceptor.java similarity index 100% rename from oxService/src/main/java/org/gluu/service/security/SecurityInterceptor.java rename to security-extension-cdi/src/main/java/org/gluu/service/security/SecurityInterceptor.java diff --git a/security-extension-cdi/src/main/resources/META-INF/beans.xml b/security-extension-cdi/src/main/resources/META-INF/beans.xml new file mode 100644 index 000000000..2f4f7e279 --- /dev/null +++ b/security-extension-cdi/src/main/resources/META-INF/beans.xml @@ -0,0 +1,7 @@ + + + diff --git a/security-extension-cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/security-extension-cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension new file mode 100644 index 000000000..4efa1a8c5 --- /dev/null +++ b/security-extension-cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension @@ -0,0 +1 @@ +org.gluu.service.security.SecurityExtension diff --git a/server/pom.xml b/server/pom.xml index 9e4aac169..129b23184 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -9,7 +9,7 @@ org.gluu oxcore - 4.0.0-SNAPSHOT + 4.5.6-SNAPSHOT diff --git a/server/src/main/java/org/gluu/server/filters/AbstractCorsFilter.java b/server/src/main/java/org/gluu/server/filters/AbstractCorsFilter.java index a7374a750..1821b78fe 100644 --- a/server/src/main/java/org/gluu/server/filters/AbstractCorsFilter.java +++ b/server/src/main/java/org/gluu/server/filters/AbstractCorsFilter.java @@ -15,6 +15,7 @@ import java.util.Enumeration; import java.util.HashSet; import java.util.Hashtable; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; @@ -117,9 +118,11 @@ public void doFilter(final ServletRequest servletRequest, // Determines the CORS request type. AbstractCorsFilter.CORSRequestType requestType = checkRequestType(request); + dumpRequestDetails("before doFilter", request, requestType); + // Adds CORS specific attributes to request. if (decorateRequest) { - AbstractCorsFilter.decorateCORSProperties(request, requestType); + decorateCORSProperties(request, requestType); } switch (requestType) { case SIMPLE: @@ -143,6 +146,8 @@ public void doFilter(final ServletRequest servletRequest, this.handleInvalidCORS(request, response, filterChain); break; } + + dumpRequestDetails("after doFilter", request, requestType); } @Override @@ -172,25 +177,28 @@ protected void handleSimpleCORS(final HttpServletRequest request, AbstractCorsFilter.CORSRequestType.SIMPLE, AbstractCorsFilter.CORSRequestType.ACTUAL)); } + dumpRequestDetails("before handleSimpleCORS", request, requestType); final String origin = request .getHeader(AbstractCorsFilter.REQUEST_HEADER_ORIGIN); final String method = request.getMethod(); // Section 6.1.2 - if (!isOriginAllowed(origin)) { + if (!isOriginAllowed(request, origin)) { + log.trace("handleSimpleCORS: handleInvalidCORS"); handleInvalidCORS(request, response, filterChain); return; } if (!allowedHttpMethods.contains(method)) { + log.trace("handleSimpleCORS: handleInvalidCORS"); handleInvalidCORS(request, response, filterChain); return; } // Section 6.1.3 // Add a single Access-Control-Allow-Origin header. - if (isAnyOriginAllowed() && !supportsCredentials) { + if (isAnyOriginAllowed(request) && !supportsCredentials) { // If resource doesn't support credentials and if any origin is // allowed // to make CORS request, return header with '*'. @@ -227,6 +235,8 @@ protected void handleSimpleCORS(final HttpServletRequest request, exposedHeadersString); } + dumpRequestDetails("after handleSimpleCORS", request, requestType); + // Forward the request down the filter chain. filterChain.doFilter(request, response); } @@ -252,11 +262,13 @@ protected void handlePreflightCORS(final HttpServletRequest request, CORSRequestType.PRE_FLIGHT.name().toLowerCase())); } + dumpRequestDetails("before handlePreflightCORS", request, requestType); + final String origin = request .getHeader(AbstractCorsFilter.REQUEST_HEADER_ORIGIN); // Section 6.2.2 - if (!isOriginAllowed(origin)) { + if (!isOriginAllowed(request, origin)) { handleInvalidCORS(request, response, filterChain); return; } @@ -310,7 +322,7 @@ protected void handlePreflightCORS(final HttpServletRequest request, AbstractCorsFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS, "true"); } else { - if (isAnyOriginAllowed()) { + if (isAnyOriginAllowed(request)) { response.addHeader( AbstractCorsFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN, "*"); @@ -340,6 +352,8 @@ protected void handlePreflightCORS(final HttpServletRequest request, join(allowedHttpHeaders, ",")); } + dumpRequestDetails("after handlePreflightCORS", request, requestType); + // Do not forward the request down the filter chain. } @@ -381,7 +395,7 @@ private void handleInvalidCORS(final HttpServletRequest request, response.setStatus(HttpServletResponse.SC_FORBIDDEN); response.resetBuffer(); - if (log.isDebugEnabled()) { + if (log.isDebugEnabled() || log.isTraceEnabled()) { // Debug so no need for i18n StringBuilder message = new StringBuilder("Invalid CORS request; Origin="); @@ -392,7 +406,7 @@ private void handleInvalidCORS(final HttpServletRequest request, message.append(";Access-Control-Request-Headers="); message.append(accessControlRequestHeaders); } - log.debug(message.toString()); + log.debug(message.toString(), new Throwable()); } } @@ -420,7 +434,7 @@ public void destroy() { * @param request The {@link HttpServletRequest} object. * @param corsRequestType The {@link CORSRequestType} object. */ - protected static void decorateCORSProperties( + protected void decorateCORSProperties( final HttpServletRequest request, final CORSRequestType corsRequestType) { if (request == null) { @@ -433,6 +447,8 @@ protected static void decorateCORSProperties( SM.getString("corsFilter.nullRequestType")); } + dumpRequestDetails("before decorateCORSProperties", request, corsRequestType); + switch (corsRequestType) { case SIMPLE: request.setAttribute( @@ -480,8 +496,9 @@ protected static void decorateCORSProperties( // Don't set any attributes break; } - } + dumpRequestDetails("after decorateCORSProperties", request, corsRequestType); + } /** * Joins elements of {@link Set} into a string, where each element is @@ -583,17 +600,23 @@ protected CORSRequestType checkRequestType(final HttpServletRequest request) { * Checks if the Origin is allowed to make a CORS request. * * @param origin The Origin. + * @param request * @return true if origin is allowed; false * otherwise. */ - private boolean isOriginAllowed(final String origin) { - if (isAnyOriginAllowed()) { + private boolean isOriginAllowed(ServletRequest servletRequest, final String origin) { + if (isAnyOriginAllowed(servletRequest)) { return true; } // If 'Origin' header is a case-sensitive match of any of allowed // origins, then return true, else return false. - return allowedOrigins.contains(origin); + if ((allowedOrigins != null) && allowedOrigins.contains(origin)) { + return true; + } + + Collection clientAllowedOrigins = getContextClientAllowedOrigins(servletRequest); + return (clientAllowedOrigins != null) && clientAllowedOrigins.contains(origin); } @@ -735,14 +758,71 @@ protected static boolean isValidOrigin(String origin) { * * @return true if it's enabled; false otherwise. */ - public boolean isAnyOriginAllowed() { - if (allowedOrigins != null && allowedOrigins.size() == 0) { - return true; - } + public boolean isAnyOriginAllowed(ServletRequest servletRequest) { + if (allowedOrigins != null && allowedOrigins.size() == 0) { + if (!hasContextClientAllowedOrigins(servletRequest)) { + return true; + } + + Collection clientAllowedOrigins = getContextClientAllowedOrigins(servletRequest); + if (clientAllowedOrigins != null && clientAllowedOrigins.size() == 0) { + return true; + } + } + + return false; + } + + protected void setContextClientAllowedOrigins(ServletRequest servletRequest, Collection clientAllowedOrigins) { + if (log.isTraceEnabled()) { + log.trace("setContextClientAllowedOrigins: {}", clientAllowedOrigins); + } + servletRequest.setAttribute(PARAM_CLIENT_ALLOWED_ORIGINS, clientAllowedOrigins); + } - return false; + @SuppressWarnings("unchecked") + protected Collection getContextClientAllowedOrigins(ServletRequest servletRequest) { + return (Collection) servletRequest.getAttribute(PARAM_CLIENT_ALLOWED_ORIGINS); } + protected boolean hasContextClientAllowedOrigins(ServletRequest servletRequest) { + Enumeration attributeNames = servletRequest.getAttributeNames(); + while (attributeNames.hasMoreElements()) { + String attributeName = attributeNames.nextElement(); + if (PARAM_CLIENT_ALLOWED_ORIGINS.equals(attributeName)) { + return true; + } + } + + return false; + } + + private void dumpRequestDetails(final String prefix, final HttpServletRequest request, final CORSRequestType corsRequestType) { + if (!log.isTraceEnabled()) { + return; + } + StringBuilder allAttributes = new StringBuilder("["); + for (Iterator it = request.getAttributeNames().asIterator(); it.hasNext();) { + if (allAttributes.length() > 1) { + allAttributes.append(","); + } + String attributeName = (String) it.next(); + allAttributes.append(attributeName).append(" = ").append(request.getAttribute(attributeName)); + } + allAttributes.append("]"); + + StringBuilder allHeaders = new StringBuilder("["); + for (Iterator it = request.getHeaderNames().asIterator(); it.hasNext();) { + if (allHeaders.length() > 1) { + allHeaders.append(","); + } + String HeaderName = (String) it.next(); + allHeaders.append(HeaderName).append(" = ").append(request.getHeader(HeaderName)); + } + allHeaders.append("]"); + + log.trace("{}: request method {} to URI {}, corsType {}, attributes {}, headers {}", prefix, request.getMethod(), request.getRequestURI(), corsRequestType, allAttributes, allHeaders); + } /** * Returns a {@link Set} of headers that should be exposed by browser. @@ -1086,6 +1166,8 @@ protected enum CORSRequestType { public static final String PARAM_CORS_REQUEST_DECORATE = "cors.request.decorate"; + public static final String PARAM_CLIENT_ALLOWED_ORIGINS = "CLIENT_ALLOWED_ORIGINS"; + } final class StringManager { @@ -1286,6 +1368,7 @@ public static StringManager getManager(String packageName, // Return the default return getManager(packageName); } + } final class Constants {