Commit 8273708a authored by Artem Hrybeniuk's avatar Artem Hrybeniuk
Browse files

Merge branch 'oauth_service_update' into 'main'

OAuthService update client id method

See merge request genesys-pgr/application-blocks!108
parents f4b97734 933fe3af
......@@ -34,6 +34,7 @@ public class ClassPKServiceTest extends ServiceTest {
// custom cleanup required for ClassPK and AuditLog tests
auditLogRepository.deleteAllInBatch();
classPkRepository.deleteAll();
super.cleanup();
}
/**
......
......@@ -20,7 +20,7 @@ import org.genesys.blocks.security.service.CustomAclService;
import org.genesys.blocks.security.service.impl.CustomAclServiceImpl;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.support.NoOpCacheManager;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
......@@ -70,7 +70,7 @@ public class ApplicationConfig {
*/
@Bean
public CacheManager cacheManager() {
return new NoOpCacheManager();
return new ConcurrentMapCacheManager();
}
/**
......
......@@ -31,6 +31,8 @@ import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
......@@ -67,6 +69,10 @@ public abstract class BaseTest {
@Autowired
protected ClassPKService classPkService;
/** The cache manager. */
@Autowired
private CacheManager cacheManager;
/**
* Cleanup.
*/
......@@ -78,6 +84,10 @@ public abstract class BaseTest {
assertThat(auditLogRepository.count(), is(0L));
LOG.trace("Deleting all from classPk");
classPkRepository.deleteAllInBatch();
LOG.trace("Clearing all caches");
cacheManager.getCacheNames().forEach(cacheName -> {
cacheManager.getCache(cacheName).clear();
});
}
/**
......
......@@ -15,11 +15,9 @@
*/
package org.genesys.blocks.config;
import java.util.Arrays;
import org.springframework.cache.CacheManager;
import org.springframework.cache.concurrent.ConcurrentMapCache;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
......@@ -35,6 +33,7 @@ import org.springframework.core.io.ClassPathResource;
@EnableAspectJAutoProxy
@Import({ DatabaseConfig.class })
@ComponentScan(basePackages = { })
@EnableCaching
public class ApplicationConfig {
/**
......@@ -60,9 +59,7 @@ public class ApplicationConfig {
*/
@Bean
public CacheManager cacheManager() {
final SimpleCacheManager cacheManager = new SimpleCacheManager();
cacheManager.setCaches(Arrays.asList(new ConcurrentMapCache("default")));
return cacheManager;
return new ConcurrentMapCacheManager();
}
}
......@@ -73,7 +73,7 @@ public class OAuthClient extends AclSid implements ClientDetails, Copyable<OAuth
/** The client id. */
@JsonView(JsonViews.Public.class)
@Column(unique = true, nullable = false, updatable = false, length = 100)
@Column(unique = true, nullable = false, length = 100)
private String clientId;
/** The client secret. */
......@@ -194,6 +194,7 @@ public class OAuthClient extends AclSid implements ClientDetails, Copyable<OAuth
}
@PrePersist
@PreUpdate
private void assignSid() {
flatten();
......@@ -204,7 +205,6 @@ public class OAuthClient extends AclSid implements ClientDetails, Copyable<OAuth
/**
* Flatten.
*/
@PreUpdate
private void flatten() {
resource = resourceIds.stream().collect(Collectors.joining(";"));
scope = scopes.stream().collect(Collectors.joining(";"));
......
......@@ -69,6 +69,16 @@ public interface OAuthClientDetailsService extends ClientDetailsService {
*/
OAuthClient updateClient(long id, int version, OAuthClient updates);
/**
* Update clientId.
*
* @param sourceId the source clientId
* @param targetId the target clientId
*
* @return the o auth client
*/
OAuthClient updateClientId(String sourceId, String targetId);
/**
* Removes the client.
*
......
......@@ -27,10 +27,13 @@ import org.genesys.blocks.oauth.model.OAuthClient;
import org.genesys.blocks.oauth.model.OAuthRole;
import org.genesys.blocks.oauth.model.QOAuthClient;
import org.genesys.blocks.oauth.persistence.OAuthClientRepository;
import org.genesys.blocks.security.service.impl.CustomAclServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
......@@ -69,6 +72,10 @@ public class OAuthServiceImpl implements OAuthClientDetailsService {
@Autowired
public PasswordEncoder passwordEncoder;
/** The cache manager. */
@Autowired(required = false)
private CacheManager cacheManager;
/*
* (non-Javadoc)
* @see org.springframework.security.oauth2.provider.ClientDetailsService#
......@@ -173,6 +180,25 @@ public class OAuthServiceImpl implements OAuthClientDetailsService {
return lazyLoad(oauthClientRepository.save(client));
}
@Override
@Transactional
@CacheEvict(cacheNames = { "oauthclient" }, key = "#sourceId", condition = "#sourceId != null && #targetId != null")
public OAuthClient updateClientId(String sourceId, String targetId) {
OAuthClient client = getClient(sourceId);
client.setClientId(targetId);
if (cacheManager!=null) {
// We need to clear sid names cache manually. Duplicate @CacheEvict annotations are not allowed.
final Cache sidNamesCache = cacheManager.getCache(CustomAclServiceImpl.CACHE_SID_NAMES);
if (sidNamesCache != null) {
sidNamesCache.evict(sourceId);
sidNamesCache.evict(client.getId());
}
}
return lazyLoad(oauthClientRepository.save(client));
}
@Override
public List<OAuthClient> autocompleteClients(final String term, int limit) {
if (StringUtils.isBlank(term) || term.length() < 1)
......
......@@ -59,6 +59,8 @@ import org.springframework.transaction.annotation.Transactional;
@Transactional
public class CustomAclServiceImpl implements CustomAclService {
public static final String CACHE_SID_NAMES = "aclSidNames";
/** The base permissions. */
private static Permission[] basePermissions;
......@@ -102,7 +104,7 @@ public class CustomAclServiceImpl implements CustomAclService {
@Override
@Transactional(readOnly = true)
@Cacheable(cacheNames = { "aclSidNames" }, key = "#id", unless = "#result == null")
@Cacheable(cacheNames = { CACHE_SID_NAMES }, key = "#id", unless = "#result == null")
public String getSidName(long id) {
AclSid sid = aclSidPersistence.findById(id).orElse(null);
return sid == null ? null : sid.getSid();
......@@ -110,7 +112,7 @@ public class CustomAclServiceImpl implements CustomAclService {
@Override
@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_UNCOMMITTED)
@Cacheable(cacheNames = { "aclSidNames" }, key = "#sid", unless = "#result == null")
@Cacheable(cacheNames = { CACHE_SID_NAMES }, key = "#sid", unless = "#result == null")
public Long getSidId(String sid) {
return aclSidPersistence.getSidId(sid);
}
......
......@@ -32,7 +32,9 @@ import org.genesys.blocks.oauth.model.OAuthRole;
import org.genesys.blocks.security.NotUniqueUserException;
import org.genesys.blocks.security.UserException;
import org.genesys.blocks.security.model.UserRole;
import org.genesys.blocks.security.persistence.AclSidPersistence;
import org.genesys.blocks.security.rest.AbstractRestTest;
import org.genesys.blocks.security.service.CustomAclService;
import org.genesys.blocks.security.service.PasswordPolicy.PasswordPolicyException;
import org.junit.Before;
import org.junit.Test;
......@@ -53,6 +55,12 @@ public class OAuthClientTest extends AbstractRestTest {
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private AclSidPersistence aclSidRepository;
@Autowired
private CustomAclService aclService;
/**
* Sets the up.
*/
......@@ -103,7 +111,36 @@ public class OAuthClientTest extends AbstractRestTest {
assertThat("Autocomplete must return the 1 client", oauthClientDetailsService.autocompleteClients(updatedClient.getTitle().substring(0, 10), 10), hasSize(1));
assertThat("Autocomplete must return the 1 client", oauthClientDetailsService.autocompleteClients(updatedClient.getTitle().substring(0, 5), 10), hasSize(1));
}
@Test
public void updateClientId() {
OAuthClient client = oauthClientDetailsService.addClient(makeClient());
assertThat(aclService.getSidName(client.getId()), is(client.getClientId()));
assertThat(aclService.getSidId(client.getClientId()), is(client.getId()));
var sid = aclSidRepository.findById(client.getId()).orElse(null);
assertThat(sid, not(nullValue()));
assertThat(sid.getSid(), is(client.getClientId()));
String originalSecret = client.getClientSecret();
String originalClientId = client.getClientId();
String targetClientId = "updatedClientId";
OAuthClient updatedClient = oauthClientDetailsService.updateClientId(originalClientId, targetClientId);
assertThat("OAuthClient#clientId must be updated", updatedClient.getClientId(), is(targetClientId));
assertThat("OAuthClient#clientSecret must not be updated", updatedClient.getClientSecret(), is(originalSecret));
assertThat("OAuthClient#publicRecaptchaKey must not be updated", updatedClient.getPublicRecaptchaKey(), is(client.getPublicRecaptchaKey()));
assertThat("OAuthClient#privateRecaptchaKey must not be updated", updatedClient.getPrivateRecaptchaKey(), is(client.getPrivateRecaptchaKey()));
sid = aclSidRepository.findById(updatedClient.getId()).orElse(null);
assertThat(sid, not(nullValue()));
assertThat(sid.getSid(), is(updatedClient.getClientId()));
assertThat(oauthClientDetailsService.getClient(targetClientId), is(notNullValue()));
assertThat(aclService.getSidName(client.getId()), is(updatedClient.getClientId()));
assertThat(aclService.getSidId(updatedClient.getClientId()), is(updatedClient.getId()));
}
/**
* Reset secret.
......
......@@ -15,7 +15,6 @@
*/
package org.genesys.blocks.security.config;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
......@@ -31,8 +30,8 @@ import org.genesys.blocks.security.service.PasswordPolicy.PasswordPolicyExceptio
import org.genesys.blocks.security.service.impl.BasicUserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.concurrent.ConcurrentMapCache;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
......@@ -57,6 +56,7 @@ import com.google.common.collect.Sets;
@EnableAspectJAutoProxy
@Import({ DatabaseConfig.class })
@ComponentScan(basePackages = { "org.genesys.blocks.security.service", "org.genesys.blocks.security.component" })
@EnableCaching
public class ApplicationConfig {
/**
......@@ -82,9 +82,7 @@ public class ApplicationConfig {
*/
@Bean
public CacheManager cacheManager() {
final SimpleCacheManager cacheManager = new SimpleCacheManager();
cacheManager.setCaches(Arrays.asList(new ConcurrentMapCache("default")));
return cacheManager;
return new ConcurrentMapCacheManager();
}
/**
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment