From fbe67cdc0d31a85588fe50f22b85b1d7f54aae05 Mon Sep 17 00:00:00 2001 From: dianw Date: Sat, 20 Oct 2018 21:41:00 +0700 Subject: [PATCH 1/5] Upgrade to spring boot 2 (#65) and drop spring social (#76) --- pom.xml | 73 ++---- .../client/OAuth2ClientRestData.java | 4 +- .../core/data/AuditInformationAuditor.java | 6 +- .../core/data/FlakeIdGenerator.java | 4 +- .../theskeleton/core/data/S3ClientConfig.java | 35 --- .../core/data/UTCDateTimeProvider.java | 12 +- .../theskeleton/core/mail/EmailConfig.java | 10 +- .../core/mail/ThymeleafTemplateService.java | 62 +++++ .../core/security/WebSecurityConfig.java | 6 +- .../core/security/WebSessionConfig.java | 4 +- .../theskeleton/core/social/SocialConfig.java | 130 --------- .../social/SocialUsersConnectionService.java | 58 ---- .../theskeleton/core/web/WebMvcConfig.java | 8 +- .../gallery/impl/GalleryServiceImpl.java | 2 +- .../theskeleton/post/PostRestData.java | 2 +- .../post/impl/PostServiceImpl.java | 2 +- .../registration/RegistrationController.java | 14 +- .../impl/RegistrationServiceImpl.java | 10 +- .../theskeleton/role/RoleRestData.java | 2 +- .../social/SocialConnectionService.java | 205 --------------- .../theskeleton/social/SocialUserEntity.java | 30 --- .../theskeleton/social/SocialUserService.java | 38 --- .../theskeleton/user/UserMapper.java | 10 - .../theskeleton/user/UserRestData.java | 2 +- .../user/UserSocialRestController.java | 59 ----- src/main/resources/application.yml | 22 +- .../OAuth2ClientRestControllerTest.java | 9 +- .../core/data/S3ClientConfigTest.java | 7 - .../core/security/SecurityConfigTest.java | 34 +-- .../core/security/SecurityTest.java | 13 - .../core/social/SocialConfigTest.java | 48 ---- .../SocialUsersConnectionServiceTest.java | 97 ------- .../follower/UserFollowerServiceTest.java | 6 +- .../gallery/GalleryServiceTest.java | 10 +- .../theskeleton/post/PostServiceTest.java | 2 +- .../privilege/PrivilegeServiceTest.java | 2 +- .../RegistrationControllerTest.java | 3 - .../theskeleton/role/RoleServiceTest.java | 3 +- .../social/SocialConnectionServiceTest.java | 247 ------------------ .../social/SocialUserServiceTest.java | 48 ---- .../user/UserSocialRestControllerTest.java | 167 ------------ 41 files changed, 155 insertions(+), 1351 deletions(-) create mode 100644 src/main/java/org/codenergic/theskeleton/core/mail/ThymeleafTemplateService.java delete mode 100644 src/main/java/org/codenergic/theskeleton/core/social/SocialConfig.java delete mode 100644 src/main/java/org/codenergic/theskeleton/core/social/SocialUsersConnectionService.java delete mode 100644 src/main/java/org/codenergic/theskeleton/social/SocialConnectionService.java delete mode 100644 src/main/java/org/codenergic/theskeleton/social/SocialUserEntity.java delete mode 100644 src/main/java/org/codenergic/theskeleton/social/SocialUserService.java delete mode 100644 src/main/java/org/codenergic/theskeleton/user/UserSocialRestController.java delete mode 100644 src/test/java/org/codenergic/theskeleton/core/social/SocialConfigTest.java delete mode 100644 src/test/java/org/codenergic/theskeleton/core/social/SocialUsersConnectionServiceTest.java delete mode 100644 src/test/java/org/codenergic/theskeleton/social/SocialConnectionServiceTest.java delete mode 100644 src/test/java/org/codenergic/theskeleton/social/SocialUserServiceTest.java delete mode 100644 src/test/java/org/codenergic/theskeleton/user/UserSocialRestControllerTest.java diff --git a/pom.xml b/pom.xml index 09df2c8..8fd5162 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 org.codenergic.theskeleton theskeleton-server - 0.12.0-SNAPSHOT + 0.20.0-SNAPSHOT TheSkeleton Server TheSkeleton is the full-stack project template used to help developer building modern web application quickly. @@ -24,24 +24,20 @@ 4.1.0 - 3.7 + 3.8.1 1.1.0 - 21.0 - 2.6.3 - 0.8.1 - 8.4.2 + 26.0-jre + 2.7.1 + 0.8.2 1.3.0.Beta1 - 3.7.0 - 2.2.4 + 3.8.0 + 2.2.5 3.1.0 - 3.0.6 - 2.18.3 - 1.5.13.RELEASE + 5.0.1 + 2.0.5.RELEASE 0.6.3 - 1.2.4.RELEASE - 1.1.3 - 1.1.6.RELEASE - 1.3.6 + 2.0.2.RELEASE + 2.0.5.RELEASE UTF-8 UTF-8 1.8 @@ -53,18 +49,6 @@ spring-boot-starter-test test - - org.mockito - mockito-core - ${mockito.version} - test - - - org.mockito - mockito-inline - ${mockito.version} - test - @@ -94,16 +78,13 @@ spring-boot-starter-security - org.springframework.security - spring-security-jwt - - - org.springframework.security.oauth - spring-security-oauth2 + org.springframework.security.oauth.boot + spring-security-oauth2-autoconfigure + ${spring-security-oauth-version} org.springframework.session - spring-session + spring-session-core org.springframework.security @@ -111,33 +92,15 @@ test - - - org.springframework.social - spring-social-security - ${spring-social-security.version} - - - org.springframework.social - spring-social-facebook - - - com.github.spring-social - spring-social-google - ${spring-social-google.version} - - org.springframework.restdocs spring-restdocs-core - ${spring-restdocs.version} test org.springframework.restdocs spring-restdocs-mockmvc - ${spring-restdocs.version} test @@ -202,7 +165,7 @@ it.ozimov - spring-boot-thymeleaf-email + spring-boot-email-core ${spring-boot-email.version} @@ -211,9 +174,7 @@ org.springframework.boot - - spring-boot-starter-data-redis - + spring-boot-starter-data-redis diff --git a/src/main/java/org/codenergic/theskeleton/client/OAuth2ClientRestData.java b/src/main/java/org/codenergic/theskeleton/client/OAuth2ClientRestData.java index 8baf0a6..92f555d 100644 --- a/src/main/java/org/codenergic/theskeleton/client/OAuth2ClientRestData.java +++ b/src/main/java/org/codenergic/theskeleton/client/OAuth2ClientRestData.java @@ -3,10 +3,10 @@ import java.util.Set; import javax.annotation.Nullable; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; import org.codenergic.theskeleton.core.data.RestData; -import org.hibernate.validator.constraints.NotBlank; -import org.hibernate.validator.constraints.NotEmpty; import org.immutables.value.Value; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; diff --git a/src/main/java/org/codenergic/theskeleton/core/data/AuditInformationAuditor.java b/src/main/java/org/codenergic/theskeleton/core/data/AuditInformationAuditor.java index f5396e3..e50da01 100644 --- a/src/main/java/org/codenergic/theskeleton/core/data/AuditInformationAuditor.java +++ b/src/main/java/org/codenergic/theskeleton/core/data/AuditInformationAuditor.java @@ -1,5 +1,7 @@ package org.codenergic.theskeleton.core.data; +import java.util.Optional; + import org.codenergic.theskeleton.core.security.User; import org.springframework.data.domain.AuditorAware; import org.springframework.security.core.Authentication; @@ -8,13 +10,13 @@ public class AuditInformationAuditor implements AuditorAware { @Override - public AuditInformation getCurrentAuditor() { + public Optional getCurrentAuditor() { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); AuditInformation auditInformation = new AuditInformation(); if (authentication instanceof OAuth2Authentication) auditInformation.setClientId(((OAuth2Authentication) authentication).getOAuth2Request().getClientId()); if (authentication.getPrincipal() instanceof User) auditInformation.setUserId(((User) authentication.getPrincipal()).getId()); - return auditInformation; + return Optional.of(auditInformation); } } diff --git a/src/main/java/org/codenergic/theskeleton/core/data/FlakeIdGenerator.java b/src/main/java/org/codenergic/theskeleton/core/data/FlakeIdGenerator.java index a111156..1541fbe 100644 --- a/src/main/java/org/codenergic/theskeleton/core/data/FlakeIdGenerator.java +++ b/src/main/java/org/codenergic/theskeleton/core/data/FlakeIdGenerator.java @@ -18,7 +18,7 @@ import java.io.Serializable; import org.hibernate.HibernateException; -import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.id.IdentifierGenerator; import com.github.rholder.fauxflake.IdGenerators; @@ -28,7 +28,7 @@ public class FlakeIdGenerator implements IdentifierGenerator { private IdGenerator flake = IdGenerators.newFlakeIdGenerator(); @Override - public Serializable generate(SessionImplementor session, Object object) { + public Serializable generate(SharedSessionContractImplementor session, Object object) { try { return flake.generateId(1_000).asString(); } catch (InterruptedException e) { diff --git a/src/main/java/org/codenergic/theskeleton/core/data/S3ClientConfig.java b/src/main/java/org/codenergic/theskeleton/core/data/S3ClientConfig.java index 553c634..b453303 100644 --- a/src/main/java/org/codenergic/theskeleton/core/data/S3ClientConfig.java +++ b/src/main/java/org/codenergic/theskeleton/core/data/S3ClientConfig.java @@ -17,13 +17,11 @@ import java.util.ArrayList; import java.util.List; -import java.util.Objects; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -33,7 +31,6 @@ import io.minio.MinioClient; import io.minio.errors.InvalidEndpointException; import io.minio.errors.InvalidPortException; -import io.minio.policy.PolicyType; @Configuration class S3ClientConfig { @@ -56,18 +53,6 @@ public ScheduledFuture> createBuckets(MinioClient minioClient, Sche logger.error(e.getMessage(), e); } }) - .peek(bucket -> bucket.getPolicies().stream() - .filter(Objects::nonNull) - .filter(policy -> Objects.nonNull(policy.policy)) - .filter(policy -> StringUtils.isNotBlank(policy.prefix)) - .peek(policy -> logger.info("Setting policy [{}] to bucket [{}] with prefix [{}]", policy.policy, bucket.name, policy.prefix)) - .forEach(policy -> { - try { - minioClient.setBucketPolicy(bucket.name, policy.prefix, policy.policy); - } catch (Exception e) { - logger.error(e.getMessage(), e); - } - })) .map(bucket -> bucket.name) .collect(Collectors.toList()), 5, TimeUnit.SECONDS); } @@ -108,30 +93,10 @@ public void setSecretKey(String secretKey) { public static class S3BucketProperties { private String name; - private List policies = new ArrayList<>(); - - public List getPolicies() { - return policies; - } public S3BucketProperties setName(String name) { this.name = name; return this; } } - - public static class S3BucketPolicyProperties { - private PolicyType policy; - private String prefix = "*"; - - public S3BucketPolicyProperties setPolicy(PolicyType policy) { - this.policy = policy; - return this; - } - - public S3BucketPolicyProperties setPrefix(String prefix) { - this.prefix = prefix; - return this; - } - } } diff --git a/src/main/java/org/codenergic/theskeleton/core/data/UTCDateTimeProvider.java b/src/main/java/org/codenergic/theskeleton/core/data/UTCDateTimeProvider.java index fe5573a..e031ba4 100644 --- a/src/main/java/org/codenergic/theskeleton/core/data/UTCDateTimeProvider.java +++ b/src/main/java/org/codenergic/theskeleton/core/data/UTCDateTimeProvider.java @@ -15,18 +15,20 @@ */ package org.codenergic.theskeleton.core.data; -import java.util.Calendar; +import java.time.Instant; +import java.time.temporal.TemporalAccessor; +import java.util.Optional; import java.util.TimeZone; import org.springframework.data.auditing.DateTimeProvider; -public class UTCDateTimeProvider implements DateTimeProvider { - public UTCDateTimeProvider() { +class UTCDateTimeProvider implements DateTimeProvider { + UTCDateTimeProvider() { TimeZone.setDefault(TimeZone.getTimeZone("UTC")); } @Override - public Calendar getNow() { - return Calendar.getInstance(TimeZone.getDefault()); + public Optional getNow() { + return Optional.of(Instant.now()); } } diff --git a/src/main/java/org/codenergic/theskeleton/core/mail/EmailConfig.java b/src/main/java/org/codenergic/theskeleton/core/mail/EmailConfig.java index 28d3753..e1c35cf 100644 --- a/src/main/java/org/codenergic/theskeleton/core/mail/EmailConfig.java +++ b/src/main/java/org/codenergic/theskeleton/core/mail/EmailConfig.java @@ -15,12 +15,20 @@ */ package org.codenergic.theskeleton.core.mail; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.thymeleaf.spring5.SpringTemplateEngine; import it.ozimov.springboot.mail.configuration.EnableEmailTools; +import it.ozimov.springboot.mail.service.TemplateService; @Configuration @EnableEmailTools public class EmailConfig { - + @Bean + public TemplateService thymeleafTemplateService(SpringTemplateEngine thymeleafEngine, + @Value("${spring.thymeleaf.suffix:.html}") String thymeleafSuffix) { + return new ThymeleafTemplateService(thymeleafEngine, thymeleafSuffix); + } } diff --git a/src/main/java/org/codenergic/theskeleton/core/mail/ThymeleafTemplateService.java b/src/main/java/org/codenergic/theskeleton/core/mail/ThymeleafTemplateService.java new file mode 100644 index 0000000..1daa197 --- /dev/null +++ b/src/main/java/org/codenergic/theskeleton/core/mail/ThymeleafTemplateService.java @@ -0,0 +1,62 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.codenergic.theskeleton.core.mail; + +import java.util.Map; +import java.util.Objects; + +import org.apache.commons.io.FilenameUtils; +import org.springframework.lang.NonNull; +import org.thymeleaf.context.Context; +import org.thymeleaf.spring5.SpringTemplateEngine; + +import com.google.common.base.Preconditions; +import com.google.common.base.Strings; +import com.google.common.io.Files; + +import it.ozimov.springboot.mail.service.TemplateService; + +class ThymeleafTemplateService implements TemplateService { + private final SpringTemplateEngine thymeleafEngine; + private final String thymeleafSuffix; + + ThymeleafTemplateService(SpringTemplateEngine thymeleafEngine, String thymeleafSuffix) { + this.thymeleafEngine = thymeleafEngine; + this.thymeleafSuffix = thymeleafSuffix; + } + + @NonNull + public String mergeTemplateIntoString(@NonNull String templateReference, @NonNull Map model) { + String trimmedTemplateReference = templateReference.trim(); + Preconditions.checkArgument(!Strings.isNullOrEmpty(trimmedTemplateReference), "The given template is null, empty or blank"); + if (trimmedTemplateReference.contains(".")) { + Preconditions.checkArgument(Objects.equals(this.getNormalizedFileExtension(trimmedTemplateReference), this.expectedTemplateExtension()), "Expected a Thymeleaf template file with extension '%s', while '%s' was given. To check the default extension look at 'spring.thymeleaf.suffix' in your application.properties file", this.expectedTemplateExtension(), this.getNormalizedFileExtension(trimmedTemplateReference)); + } + + Context context = new Context(); + context.setVariables(model); + return this.thymeleafEngine.process(FilenameUtils.removeExtension(trimmedTemplateReference), context); + } + + public String expectedTemplateExtension() { + return this.thymeleafSuffix; + } + + private String getNormalizedFileExtension(String templateReference) { + return "." + Files.getFileExtension(templateReference); + } +} diff --git a/src/main/java/org/codenergic/theskeleton/core/security/WebSecurityConfig.java b/src/main/java/org/codenergic/theskeleton/core/security/WebSecurityConfig.java index 614dd95..4918057 100644 --- a/src/main/java/org/codenergic/theskeleton/core/security/WebSecurityConfig.java +++ b/src/main/java/org/codenergic/theskeleton/core/security/WebSecurityConfig.java @@ -36,7 +36,6 @@ import org.springframework.security.web.authentication.RememberMeServices; import org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; -import org.springframework.social.security.SpringSocialConfigurer; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; @@ -103,8 +102,7 @@ protected void configure(HttpSecurity http) throws Exception { .csrf() .requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/authorize")) .disable() - .cors().and() - .apply(new SpringSocialConfigurer()); + .cors(); } /** @@ -123,7 +121,7 @@ public FilterRegistrationBean corsFilterBean() { configuration.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type")); final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); - FilterRegistrationBean corsFilter = new FilterRegistrationBean(new CorsFilter(source)); + FilterRegistrationBean corsFilter = new FilterRegistrationBean<>(new CorsFilter(source)); corsFilter.setOrder(Ordered.HIGHEST_PRECEDENCE); return corsFilter; } diff --git a/src/main/java/org/codenergic/theskeleton/core/security/WebSessionConfig.java b/src/main/java/org/codenergic/theskeleton/core/security/WebSessionConfig.java index 0810d00..655d954 100644 --- a/src/main/java/org/codenergic/theskeleton/core/security/WebSessionConfig.java +++ b/src/main/java/org/codenergic/theskeleton/core/security/WebSessionConfig.java @@ -15,6 +15,8 @@ */ package org.codenergic.theskeleton.core.security; +import java.util.concurrent.ConcurrentHashMap; + import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.core.session.SessionRegistry; @@ -34,7 +36,7 @@ public RememberMeServices rememberMeServices() { @Bean public MapSessionRepository sessionRepository() { - return new MapSessionRepository(); + return new MapSessionRepository(new ConcurrentHashMap<>()); } @Bean diff --git a/src/main/java/org/codenergic/theskeleton/core/social/SocialConfig.java b/src/main/java/org/codenergic/theskeleton/core/social/SocialConfig.java deleted file mode 100644 index 3d46bcb..0000000 --- a/src/main/java/org/codenergic/theskeleton/core/social/SocialConfig.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * * - * http://www.apache.org/licenses/LICENSE-2.0 - * * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.codenergic.theskeleton.core.social; - -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; - -import javax.annotation.PostConstruct; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.codenergic.theskeleton.core.security.User; -import org.codenergic.theskeleton.social.SocialConnectionRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.social.FacebookAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.web.savedrequest.HttpSessionRequestCache; -import org.springframework.security.web.savedrequest.RequestCache; -import org.springframework.security.web.savedrequest.SavedRequest; -import org.springframework.social.UserIdSource; -import org.springframework.social.config.annotation.EnableSocial; -import org.springframework.social.config.annotation.SocialConfigurerAdapter; -import org.springframework.social.connect.ConnectionFactoryLocator; -import org.springframework.social.connect.UsersConnectionRepository; -import org.springframework.social.connect.support.OAuth2ConnectionFactory; -import org.springframework.social.connect.web.ProviderSignInController; -import org.springframework.social.connect.web.ProviderSignInUtils; -import org.springframework.social.connect.web.SignInAdapter; -import org.springframework.social.google.config.boot.GoogleAutoConfiguration; - -@Configuration -@EnableSocial -@Import({FacebookAutoConfiguration.class, GoogleAutoConfiguration.class}) -public class SocialConfig extends SocialConfigurerAdapter { - /** - * generator-jhipster/issues/2349 - */ - private static final String[] PROFILE_FIELDS = { - "id", "about", "age_range", "birthday", "context", "cover", "currency", "devices", "education", "email", - "favorite_athletes", "favorite_teams", "first_name", "gender", "hometown", "inspirational_people", "installed", "install_type", - "is_verified", "languages", "last_name", "link", "locale", "location", "meeting_for", "middle_name", "name", "name_format", - "political", "quotes", "payment_pricepoints", "relationship_status", "religion", "security_settings", "significant_other", - "sports", "test_group", "timezone", "third_party_id", "updated_time", "verified", "video_upload_limits", "viewer_can_send_gift", - "website", "work" - }; - - private final SocialConnectionRepository socialConnectionRepository; - - public SocialConfig(SocialConnectionRepository socialConnectionRepository) { - this.socialConnectionRepository = socialConnectionRepository; - } - - @PostConstruct - public void init() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException { - Field field = Class.forName("org.springframework.social.facebook.api.UserOperations"). - getDeclaredField("PROFILE_FIELDS"); - field.setAccessible(true); - Field modifiers = field.getClass().getDeclaredField("modifiers"); - modifiers.setAccessible(true); - modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL); - field.set(null, PROFILE_FIELDS); - } - - @Autowired - public void connectionFactories(ConnectionFactoryLocator connectionFactoryLocator) { - OAuth2ConnectionFactory fbConnectionFactory = (OAuth2ConnectionFactory) connectionFactoryLocator.getConnectionFactory("facebook"); - if (fbConnectionFactory != null) - fbConnectionFactory.setScope("email public_profile user_link"); - } - - @Override - public UserIdSource getUserIdSource() { - return () -> { - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - if (authentication.getPrincipal() instanceof User) - return ((User) authentication.getPrincipal()).getId(); - return authentication.getName(); - }; - } - - @Override - public UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator connectionFactoryLocator) { - return new SocialUsersConnectionService(connectionFactoryLocator, socialConnectionRepository); - } - - @Bean - public ProviderSignInController providerSignInController(ConnectionFactoryLocator connectionFactoryLocator, UsersConnectionRepository usersConnectionRepository, SignInAdapter signInAdapter) { - ProviderSignInController signInController = - new ProviderSignInController(connectionFactoryLocator, usersConnectionRepository, signInAdapter); - signInController.setSignUpUrl("/registration"); - return signInController; - } - - @Bean - public ProviderSignInUtils providerSignInUtils(ConnectionFactoryLocator connectionFactoryLocator, UsersConnectionRepository connectionRepository) { - return new ProviderSignInUtils(connectionFactoryLocator, connectionRepository); - } - - @Bean - public SignInAdapter signInAdapter(UserDetailsService userDetailsService) { - RequestCache requestCache = new HttpSessionRequestCache(); - return (userId, connection, request) -> { - UserDetails userDetails = userDetailsService.loadUserByUsername(userId); - Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); - SecurityContextHolder.getContext().setAuthentication(authentication); - SavedRequest savedRequest = requestCache.getRequest(request.getNativeRequest(HttpServletRequest.class), request.getNativeResponse(HttpServletResponse.class)); - return savedRequest == null ? null : savedRequest.getRedirectUrl(); - }; - } -} diff --git a/src/main/java/org/codenergic/theskeleton/core/social/SocialUsersConnectionService.java b/src/main/java/org/codenergic/theskeleton/core/social/SocialUsersConnectionService.java deleted file mode 100644 index 15dffd1..0000000 --- a/src/main/java/org/codenergic/theskeleton/core/social/SocialUsersConnectionService.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.codenergic.theskeleton.core.social; - -import org.codenergic.theskeleton.social.SocialConnectionEntity; -import org.codenergic.theskeleton.social.SocialConnectionRepository; -import org.codenergic.theskeleton.social.SocialConnectionService; -import org.springframework.social.connect.*; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -public class SocialUsersConnectionService implements UsersConnectionRepository { - private ConnectionFactoryLocator connectionFactoryLocator; - private SocialConnectionRepository connectionRepository; - - SocialUsersConnectionService(ConnectionFactoryLocator locator, SocialConnectionRepository repository) { - this.connectionFactoryLocator = locator; - this.connectionRepository = repository; - } - - @Override - @Transactional - public List findUserIdsWithConnection(Connection connection) { - ConnectionKey key = connection.getKey(); - List localUsers = connectionRepository.findByProviderAndProviderUserId(key.getProviderId(), key.getProviderUserId()); - return localUsers.stream().map(u -> u.getUser().getId()).collect(Collectors.toList()); - } - - @Override - public Set findUserIdsConnectedTo(String providerId, Set providerUserIds) { - return connectionRepository.findByProviderAndProviderUserIdIn(providerId, providerUserIds) - .stream().map(u -> u.getUser().getId()).collect(Collectors.toSet()); - } - - @Override - @Transactional - public SocialConnectionService createConnectionRepository(String userId) { - if (userId == null) - throw new IllegalArgumentException("UserId cannot be null"); - return new SocialConnectionService(userId, connectionRepository, connectionFactoryLocator); - } -} diff --git a/src/main/java/org/codenergic/theskeleton/core/web/WebMvcConfig.java b/src/main/java/org/codenergic/theskeleton/core/web/WebMvcConfig.java index ca9127c..df8b61a 100644 --- a/src/main/java/org/codenergic/theskeleton/core/web/WebMvcConfig.java +++ b/src/main/java/org/codenergic/theskeleton/core/web/WebMvcConfig.java @@ -15,17 +15,17 @@ */ package org.codenergic.theskeleton.core.web; +import java.util.List; + import org.springframework.context.annotation.Configuration; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; - -import java.util.List; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration -public class WebMvcConfig extends WebMvcConfigurerAdapter { +public class WebMvcConfig implements WebMvcConfigurer { private final UserDetailsService userDetailsService; public WebMvcConfig(UserDetailsService userDetailsService) { diff --git a/src/main/java/org/codenergic/theskeleton/gallery/impl/GalleryServiceImpl.java b/src/main/java/org/codenergic/theskeleton/gallery/impl/GalleryServiceImpl.java index 0ce6c10..bc733c0 100644 --- a/src/main/java/org/codenergic/theskeleton/gallery/impl/GalleryServiceImpl.java +++ b/src/main/java/org/codenergic/theskeleton/gallery/impl/GalleryServiceImpl.java @@ -49,7 +49,7 @@ public GalleryServiceImpl(GalleryRepository galleryRepository, MinioClient minio @Transactional public void deleteImages(String userId, String... imagesId) { for (String imageId : imagesId) { - galleryRepository.delete(imageId); + galleryRepository.deleteById(imageId); } } diff --git a/src/main/java/org/codenergic/theskeleton/post/PostRestData.java b/src/main/java/org/codenergic/theskeleton/post/PostRestData.java index 6310b86..3b77f67 100644 --- a/src/main/java/org/codenergic/theskeleton/post/PostRestData.java +++ b/src/main/java/org/codenergic/theskeleton/post/PostRestData.java @@ -18,9 +18,9 @@ import java.util.Date; import javax.annotation.Nullable; +import javax.validation.constraints.NotBlank; import org.codenergic.theskeleton.core.data.RestData; -import org.hibernate.validator.constraints.NotBlank; import org.immutables.value.Value; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; diff --git a/src/main/java/org/codenergic/theskeleton/post/impl/PostServiceImpl.java b/src/main/java/org/codenergic/theskeleton/post/impl/PostServiceImpl.java index 60c6533..1f4d001 100644 --- a/src/main/java/org/codenergic/theskeleton/post/impl/PostServiceImpl.java +++ b/src/main/java/org/codenergic/theskeleton/post/impl/PostServiceImpl.java @@ -45,7 +45,7 @@ public PostServiceImpl(PostRepository postRepository, PostFollowingRepository po @Override public void deletePost(String id) { - postRepository.delete(id); + postRepository.deleteById(id); } @Override diff --git a/src/main/java/org/codenergic/theskeleton/registration/RegistrationController.java b/src/main/java/org/codenergic/theskeleton/registration/RegistrationController.java index 17c7474..4f1fadf 100644 --- a/src/main/java/org/codenergic/theskeleton/registration/RegistrationController.java +++ b/src/main/java/org/codenergic/theskeleton/registration/RegistrationController.java @@ -20,9 +20,6 @@ import org.codenergic.theskeleton.tokenstore.TokenStoreService; import org.codenergic.theskeleton.tokenstore.TokenStoreType; import org.codenergic.theskeleton.user.UserEntity; -import org.springframework.social.connect.Connection; -import org.springframework.social.connect.UserProfile; -import org.springframework.social.connect.web.ProviderSignInUtils; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; @@ -41,22 +38,14 @@ public class RegistrationController { private final RegistrationService registrationService; private final TokenStoreService tokenStoreService; - private final ProviderSignInUtils providerSignInUtils; - public RegistrationController(RegistrationService registrationService, TokenStoreService tokenStoreService, ProviderSignInUtils providerSignInUtils) { + public RegistrationController(RegistrationService registrationService, TokenStoreService tokenStoreService) { this.registrationService = registrationService; this.tokenStoreService = tokenStoreService; - this.providerSignInUtils = providerSignInUtils; } @GetMapping public String registrationView(RegistrationForm registrationForm, WebRequest request) { - Connection connection = providerSignInUtils.getConnectionFromSession(request); - if (connection != null) { - UserProfile profile = connection.fetchUserProfile(); - registrationForm.setUsername(profile.getUsername()); - registrationForm.setEmail(profile.getEmail()); - } return REGISTRATION; } @@ -68,7 +57,6 @@ public String register(@Valid RegistrationForm registrationForm, BindingResult b UserEntity user = registrationService.registerUser(registrationForm); if (user != null && user.getId() != null) { tokenStoreService.sendTokenNotification(TokenStoreType.USER_ACTIVATION, user); - providerSignInUtils.doPostSignUp(user.getId(), request); } } catch (RegistrationException e) { bindingResult.rejectValue("username", "error.registrationForm", e.getMessage()); diff --git a/src/main/java/org/codenergic/theskeleton/registration/impl/RegistrationServiceImpl.java b/src/main/java/org/codenergic/theskeleton/registration/impl/RegistrationServiceImpl.java index 31a93c1..0f4f595 100644 --- a/src/main/java/org/codenergic/theskeleton/registration/impl/RegistrationServiceImpl.java +++ b/src/main/java/org/codenergic/theskeleton/registration/impl/RegistrationServiceImpl.java @@ -12,14 +12,12 @@ import org.codenergic.theskeleton.user.UserEntity; import org.codenergic.theskeleton.user.UserRepository; import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.social.connect.Connection; -import org.springframework.social.connect.ConnectionSignUp; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service @Transactional(readOnly = true) -public class RegistrationServiceImpl implements RegistrationService, ConnectionSignUp { +public class RegistrationServiceImpl implements RegistrationService { private UserRepository userRepository; private TokenStoreRepository tokenStoreRepository; private PasswordEncoder passwordEncoder; @@ -87,10 +85,4 @@ public boolean changePassword(String activationToken, String password) { tokenStoreEntity.setStatus(Activeable.Status.INACTIVE.getStatus()); return true; } - - @Override - @Transactional - public String execute(Connection connection) { - throw new UnsupportedOperationException(); - } } diff --git a/src/main/java/org/codenergic/theskeleton/role/RoleRestData.java b/src/main/java/org/codenergic/theskeleton/role/RoleRestData.java index dadaa40..f2aa292 100644 --- a/src/main/java/org/codenergic/theskeleton/role/RoleRestData.java +++ b/src/main/java/org/codenergic/theskeleton/role/RoleRestData.java @@ -16,9 +16,9 @@ package org.codenergic.theskeleton.role; import javax.annotation.Nullable; +import javax.validation.constraints.NotBlank; import org.codenergic.theskeleton.core.data.RestData; -import org.hibernate.validator.constraints.NotBlank; import org.immutables.value.Value; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; diff --git a/src/main/java/org/codenergic/theskeleton/social/SocialConnectionService.java b/src/main/java/org/codenergic/theskeleton/social/SocialConnectionService.java deleted file mode 100644 index 4aaf212..0000000 --- a/src/main/java/org/codenergic/theskeleton/social/SocialConnectionService.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright 2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.codenergic.theskeleton.social; - -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.stream.Collectors; - -import org.codenergic.theskeleton.user.UserEntity; -import org.springframework.security.crypto.encrypt.Encryptors; -import org.springframework.security.crypto.encrypt.TextEncryptor; -import org.springframework.social.connect.Connection; -import org.springframework.social.connect.ConnectionData; -import org.springframework.social.connect.ConnectionFactory; -import org.springframework.social.connect.ConnectionFactoryLocator; -import org.springframework.social.connect.ConnectionKey; -import org.springframework.social.connect.ConnectionRepository; -import org.springframework.social.connect.NoSuchConnectionException; -import org.springframework.social.connect.NotConnectedException; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; - -public class SocialConnectionService implements ConnectionRepository { - private ServiceProviderConnectionMapper connectionMapper = new ServiceProviderConnectionMapper(); - private String userId; - private SocialConnectionRepository connectionRepository; - private ConnectionFactoryLocator connectionFactoryLocator; - private TextEncryptor textEncryptor = Encryptors.noOpText(); - - public SocialConnectionService(String userId, SocialConnectionRepository connectionRepository, - ConnectionFactoryLocator connectionFactoryLocator) { - this.userId = userId; - this.connectionRepository = connectionRepository; - this.connectionFactoryLocator = connectionFactoryLocator; - } - - @Override - @Transactional - public void addConnection(Connection connection) { - ConnectionData data = connection.createData(); - int rank = connectionRepository.getRank(userId, data.getProviderId()); - - SocialConnectionEntity userConnection = new SocialConnectionEntity() - .setUser(new UserEntity().setId(userId)) - .setProvider(data.getProviderId()) - .setProviderUserId(data.getProviderUserId()) - .setRank(rank) - .setDisplayName(data.getDisplayName()) - .setProfileUrl(data.getProfileUrl()) - .setImageUrl(data.getImageUrl()) - .setAccessToken(encrypt(data.getAccessToken())) - .setSecret(encrypt(data.getSecret())) - .setRefreshToken(encrypt(data.getRefreshToken())) - .setExpireTime(data.getExpireTime()); - connectionRepository.save(userConnection); - } - - private String encrypt(String text) { - return text == null ? null : textEncryptor.encrypt(text); - } - - @Override - public MultiValueMap> findAllConnections() { - List socialConnections = connectionRepository.findByUserIdOrderByRankAsc(userId); - Map>> connections = socialConnections.stream() - .map(connectionMapper::mapRow) - .collect(Collectors.groupingBy(connection -> connection.getKey().getProviderId())); - return new LinkedMultiValueMap<>(connections); - } - - @Override - public List> findConnections(String providerId) { - return connectionRepository.findByUserIdAndProviderOrderByRankAsc(userId, providerId) - .stream() - .map(connectionMapper::mapRow) - .collect(Collectors.toList()); - } - - @SuppressWarnings("unchecked") - @Override - public List> findConnections(Class apiType) { - List connections = findConnections(getProviderId(apiType)); - return (List>) connections; - } - - @Override - public MultiValueMap> findConnectionsToUsers(MultiValueMap providerUserIds) { - throw new UnsupportedOperationException(); - } - - @SuppressWarnings("unchecked") - @Override - public Connection findPrimaryConnection(Class apiType) { - String providerId = getProviderId(apiType); - return (Connection) findPrimaryConnection(providerId) - .orElseThrow(() -> new NotConnectedException(providerId)); - } - - private Optional> findPrimaryConnection(String providerId) { - List socialConnections = connectionRepository.findByUserIdAndProviderAndRank(userId, providerId, 1); - return socialConnections.stream() - .map(connection -> connectionMapper.mapRow(connection)) - .findFirst(); - } - - @Override - public Connection getConnection(ConnectionKey connectionKey) { - return connectionRepository - .findByUserIdAndProviderAndProviderUserId(userId, connectionKey.getProviderId(), connectionKey.getProviderUserId()) - .map(connectionMapper::mapRow) - .orElseThrow(() -> new NoSuchConnectionException(connectionKey)); - } - - @SuppressWarnings("unchecked") - @Override - public Connection getConnection(Class apiType, - String providerUserId) { - String providerId = getProviderId(apiType); - return (Connection) getConnection(new ConnectionKey(providerId, providerUserId)); - } - - @SuppressWarnings("unchecked") - @Override - public Connection getPrimaryConnection(Class apiType) { - String providerId = getProviderId(apiType); - return (Connection) findPrimaryConnection(providerId) - .orElseThrow(() -> new NotConnectedException(providerId)); - } - - private String getProviderId(Class apiType) { - return connectionFactoryLocator.getConnectionFactory(apiType).getProviderId(); - } - - @Override - public void removeConnection(ConnectionKey connectionKey) { - SocialConnectionEntity connection = connectionRepository - .findByUserIdAndProviderAndProviderUserId(userId, connectionKey.getProviderId(), connectionKey.getProviderUserId()) - .orElseThrow(() -> new NoSuchConnectionException(connectionKey)); - connectionRepository.delete(connection); - } - - @Override - @Transactional - public void removeConnections(String providerId) { - List connections = connectionRepository.findByUserIdAndProvider(userId, providerId); - connectionRepository.delete(connections); - } - - @Override - @Transactional - public void updateConnection(Connection connection) { - ConnectionData data = connection.createData(); - SocialConnectionEntity userConnection = connectionRepository - .findByUserIdAndProviderAndProviderUserId(userId, data.getProviderId(), data.getProviderUserId()) - .orElseThrow(() -> new NoSuchConnectionException(connection.getKey())) - .setDisplayName(data.getDisplayName()) - .setProfileUrl(data.getProfileUrl()) - .setImageUrl(data.getImageUrl()) - .setAccessToken(encrypt(data.getAccessToken())) - .setSecret(encrypt(data.getSecret())) - .setRefreshToken(encrypt(data.getRefreshToken())) - .setExpireTime(data.getExpireTime()); - connectionRepository.save(userConnection); - } - - private final class ServiceProviderConnectionMapper { - private String decrypt(String encryptedText) { - return encryptedText == null ? null : textEncryptor.decrypt(encryptedText); - } - - private Long expireTime(long expireTime) { - return expireTime == 0 ? null : expireTime; - } - - private ConnectionData mapConnectionData(SocialConnectionEntity connection) { - return new ConnectionData(connection.getProvider(), - connection.getProviderUserId(), connection.getDisplayName(), - connection.getProfileUrl(), connection.getImageUrl(), decrypt(connection.getAccessToken()), - decrypt(connection.getSecret()), decrypt(connection.getRefreshToken()), - expireTime(connection.getExpireTime())); - } - - Connection mapRow(SocialConnectionEntity connection) { - ConnectionData connectionData = mapConnectionData(connection); - ConnectionFactory connectionFactory = connectionFactoryLocator - .getConnectionFactory(connectionData.getProviderId()); - return connectionFactory.createConnection(connectionData); - } - } -} diff --git a/src/main/java/org/codenergic/theskeleton/social/SocialUserEntity.java b/src/main/java/org/codenergic/theskeleton/social/SocialUserEntity.java deleted file mode 100644 index 3e6bb41..0000000 --- a/src/main/java/org/codenergic/theskeleton/social/SocialUserEntity.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * * - * http://www.apache.org/licenses/LICENSE-2.0 - * * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.codenergic.theskeleton.social; - -import org.codenergic.theskeleton.user.UserEntity; -import org.springframework.social.security.SocialUserDetails; - -public class SocialUserEntity extends UserEntity implements SocialUserDetails { - SocialUserEntity(UserEntity userEntity) { - super(userEntity); - } - - @Override - public String getUserId() { - return getId(); - } -} diff --git a/src/main/java/org/codenergic/theskeleton/social/SocialUserService.java b/src/main/java/org/codenergic/theskeleton/social/SocialUserService.java deleted file mode 100644 index 9fb9917..0000000 --- a/src/main/java/org/codenergic/theskeleton/social/SocialUserService.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.codenergic.theskeleton.social; - -import org.codenergic.theskeleton.user.UserRepository; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.social.security.SocialUserDetails; -import org.springframework.social.security.SocialUserDetailsService; -import org.springframework.stereotype.Service; - -@Service -public class SocialUserService implements SocialUserDetailsService { - private final UserRepository userRepository; - - public SocialUserService(UserRepository userRepository) { - this.userRepository = userRepository; - } - - @Override - public SocialUserDetails loadUserByUserId(String userId) { - return userRepository.findById(userId) - .map(SocialUserEntity::new) - .orElseThrow(() -> new UsernameNotFoundException(userId)); - } -} diff --git a/src/main/java/org/codenergic/theskeleton/user/UserMapper.java b/src/main/java/org/codenergic/theskeleton/user/UserMapper.java index b2efa4f..f72adcc 100644 --- a/src/main/java/org/codenergic/theskeleton/user/UserMapper.java +++ b/src/main/java/org/codenergic/theskeleton/user/UserMapper.java @@ -18,8 +18,6 @@ import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.factory.Mappers; -import org.springframework.social.connect.Connection; -import org.springframework.social.connect.ConnectionData; @Mapper public interface UserMapper { @@ -35,12 +33,4 @@ static UserMapper newInstance() { @Mapping(target = "nonLocked", source = "accountNonLocked") @Mapping(target = "password", ignore = true) UserRestData toUserData(UserEntity user); - - @Mapping(target = "displayName", source = "connection.displayName") - @Mapping(target = "imageUrl", source = "connection.imageUrl") - @Mapping(target = "profileUrl", source = "connection.profileUrl") - @Mapping(target = "profileId", source = "connectionData.providerUserId") - @Mapping(target = "provider", source = "connectionData.providerId") - UserSocialRestData toUserSocialData(Connection connection, ConnectionData connectionData); - } diff --git a/src/main/java/org/codenergic/theskeleton/user/UserRestData.java b/src/main/java/org/codenergic/theskeleton/user/UserRestData.java index 8115c71..10a8107 100644 --- a/src/main/java/org/codenergic/theskeleton/user/UserRestData.java +++ b/src/main/java/org/codenergic/theskeleton/user/UserRestData.java @@ -18,11 +18,11 @@ import java.util.Set; import javax.annotation.Nullable; +import javax.validation.constraints.NotBlank; import javax.validation.constraints.Pattern; import org.codenergic.theskeleton.core.data.RestData; import org.codenergic.theskeleton.core.web.ValidationConstants; -import org.hibernate.validator.constraints.NotBlank; import org.immutables.value.Value; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; diff --git a/src/main/java/org/codenergic/theskeleton/user/UserSocialRestController.java b/src/main/java/org/codenergic/theskeleton/user/UserSocialRestController.java deleted file mode 100644 index f89f7d5..0000000 --- a/src/main/java/org/codenergic/theskeleton/user/UserSocialRestController.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2018 original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.codenergic.theskeleton.user; - -import java.util.List; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; - -import org.springframework.social.connect.Connection; -import org.springframework.social.connect.ConnectionRepository; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping("/api/users/{username}/socials") -public class UserSocialRestController { - private final ConnectionRepository connectionRepository; - private final UserMapper userMapper = UserMapper.newInstance(); - - public UserSocialRestController(ConnectionRepository connectionRepository) { - this.connectionRepository = connectionRepository; - } - - private UserSocialRestData mapConnections(Map.Entry>> e) { - Connection connection = e.getValue().get(0); - return userMapper.toUserSocialData(connection, connection.createData()); - } - - @DeleteMapping - public void removeUserSocialConnection(@RequestBody String provider) { - connectionRepository.removeConnections(provider); - } - - @GetMapping - public Map findUserSocialConnections() { - return connectionRepository.findAllConnections().entrySet() - .stream() - .map(this::mapConnections) - .collect(Collectors.toMap(UserSocialRestData::getProvider, Function.identity())); - } -} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 9743461..b93aaaa 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -12,7 +12,6 @@ logging: level: org.codenergic.theskeleton: DEBUG management: - context-path: /manage info: git: mode: full @@ -23,19 +22,7 @@ s3: secret-key: supersecret123 buckets: - name: profile-pictures - policies: - - prefix: '*' - policy: READ_ONLY - name: galleries - policies: - - prefix: '*' - policy: READ_ONLY -security: - jwt: - signing-key: VNcRqdXpj9nHZQqtmf5l - oauth2: - resource: - filter-order: 3 spring: datasource: url: jdbc:h2:~/.theskeleton;AUTO_SERVER=TRUE @@ -58,8 +45,6 @@ spring: region: factory_class: org.hibernate.cache.ehcache.EhCacheRegionFactory use_second_level_cache: true - thymeleaf: - cache: false mail: host: localhost port: 1025 @@ -74,6 +59,11 @@ spring: starttls: enable: false required: false + security: + filter: + order: 3 + jwt: + signing-key: VNcRqdXpj9nHZQqtmf5l social: facebook: app-id: 897090537127510 @@ -81,5 +71,7 @@ spring: google: app-id: 1031466054059-efbl8kv8luoegprdsdubkq4kba3qvcuo.apps.googleusercontent.com app-secret: pTj_xuAmNSmx0nOhTTsMpCZN + thymeleaf: + cache: false email: baseurl: http://localhost:8080 diff --git a/src/test/java/org/codenergic/theskeleton/client/OAuth2ClientRestControllerTest.java b/src/test/java/org/codenergic/theskeleton/client/OAuth2ClientRestControllerTest.java index 8b16b31..f5d358d 100644 --- a/src/test/java/org/codenergic/theskeleton/client/OAuth2ClientRestControllerTest.java +++ b/src/test/java/org/codenergic/theskeleton/client/OAuth2ClientRestControllerTest.java @@ -33,7 +33,6 @@ import org.springframework.data.web.config.EnableSpringDataWebSupport; import org.springframework.http.MediaType; import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; @@ -57,7 +56,7 @@ @RunWith(SpringRunner.class) @EnableSpringDataWebSupport -@WebMvcTest(controllers = {OAuth2ClientRestController.class}) +@WebMvcTest(controllers = {OAuth2ClientRestController.class}, secure = false) @EnableRestDocs @InjectUserDetailsService public class OAuth2ClientRestControllerTest { @@ -70,7 +69,6 @@ public class OAuth2ClientRestControllerTest { private final OAuth2ClientMapper oAuth2ClientMapper = OAuth2ClientMapper.newInstance(); @Test - @WithMockUser("user123") public void testDeleteClient() throws Exception { mockMvc.perform(delete("/api/clients/client123") .contentType(MediaType.APPLICATION_JSON)) @@ -79,7 +77,6 @@ public void testDeleteClient() throws Exception { } @Test - @WithMockUser("user123") public void testFindClientById() throws Exception { final OAuth2ClientEntity client = new OAuth2ClientEntity() .setId("client123") @@ -103,7 +100,6 @@ public void testFindClientById() throws Exception { } @Test - @WithMockUser("user123") public void testFindClients() throws Exception { final OAuth2ClientEntity client = new OAuth2ClientEntity() .setId("client123") @@ -129,7 +125,6 @@ public void testFindClients() throws Exception { } @Test - @WithMockUser("user123") public void testGenerateClientSecret() throws Exception { final OAuth2ClientEntity client = new OAuth2ClientEntity() .setId("client123"); @@ -147,7 +142,6 @@ public void testGenerateClientSecret() throws Exception { } @Test - @WithMockUser("user123") public void testSaveClient() throws Exception { final OAuth2ClientEntity client = new OAuth2ClientEntity() .setId("client123") @@ -189,7 +183,6 @@ public void testSerializeDeserializeClient() throws IOException { } @Test - @WithMockUser("user123") public void testUpdateClient() throws Exception { final OAuth2ClientEntity client = new OAuth2ClientEntity() .setId("client123"); diff --git a/src/test/java/org/codenergic/theskeleton/core/data/S3ClientConfigTest.java b/src/test/java/org/codenergic/theskeleton/core/data/S3ClientConfigTest.java index 19ca0c7..a8fc021 100644 --- a/src/test/java/org/codenergic/theskeleton/core/data/S3ClientConfigTest.java +++ b/src/test/java/org/codenergic/theskeleton/core/data/S3ClientConfigTest.java @@ -28,13 +28,11 @@ import io.minio.MinioClient; import io.minio.errors.InvalidBucketNameException; -import io.minio.policy.PolicyType; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -56,9 +54,6 @@ public void init() { Stream.of("test1", "test2").forEach(bucketName -> { S3ClientConfig.S3BucketProperties bucketProperties = new S3ClientConfig.S3BucketProperties(); bucketProperties.setName(bucketName); - bucketProperties.getPolicies().add(new S3ClientConfig.S3BucketPolicyProperties() - .setPolicy(PolicyType.NONE) - .setPrefix("*")); s3ClientProperties.getBuckets().add(bucketProperties); }); } @@ -74,12 +69,10 @@ public void testCreateBucket() throws Exception { }); when(minioClient.bucketExists(eq("test1"))).thenReturn(true); when(minioClient.bucketExists(eq("test2"))).thenReturn(false); - doThrow(new RuntimeException()).when(minioClient).setBucketPolicy(eq("test2"), anyString(), any()); s3ClientConfig.createBuckets(minioClient, executorService, s3ClientProperties); verify(minioClient, times(2)).bucketExists(anyString()); verify(minioClient).makeBucket(eq("test2")); verify(executorService).schedule(argumentCaptor.capture(), anyLong(), any()); - verify(minioClient, times(2)).setBucketPolicy(anyString(), anyString(), any()); when(minioClient.bucketExists(anyString())).thenThrow(InvalidBucketNameException.class); s3ClientConfig.createBuckets(minioClient, executorService, s3ClientProperties); } diff --git a/src/test/java/org/codenergic/theskeleton/core/security/SecurityConfigTest.java b/src/test/java/org/codenergic/theskeleton/core/security/SecurityConfigTest.java index cde0f20..a5cf1d7 100644 --- a/src/test/java/org/codenergic/theskeleton/core/security/SecurityConfigTest.java +++ b/src/test/java/org/codenergic/theskeleton/core/security/SecurityConfigTest.java @@ -29,23 +29,23 @@ public class SecurityConfigTest { private SecurityConfig securityConfig = new SecurityConfig(); - @Test - public void testAccessTokenConverter() throws Exception { - ResourceLoader resourceLoader = new DefaultResourceLoader(); - JwtAccessTokenConverter hmacTokenConverter = (JwtAccessTokenConverter) securityConfig.accessTokenConverter("", resourceLoader); - assertThat(hmacTokenConverter.getKey()).containsKeys("alg", "value"); - assertThat(hmacTokenConverter.getKey()).containsEntry("alg", "HMACSHA256"); - assertThat(hmacTokenConverter.getKey().get("value")).hasSize(6); - JwtAccessTokenConverter hmacTokenConverter2 = (JwtAccessTokenConverter) securityConfig.accessTokenConverter("1234", resourceLoader); - assertThat(hmacTokenConverter2.getKey()).containsKeys("alg", "value"); - assertThat(hmacTokenConverter2.getKey()).containsEntry("alg", "HMACSHA256"); - assertThat(hmacTokenConverter2.getKey().get("value")).hasSize(4); - JwtAccessTokenConverter rsaTokenConverter = (JwtAccessTokenConverter) securityConfig.accessTokenConverter("classpath:/jwt-signing-key.pem", resourceLoader); - rsaTokenConverter.afterPropertiesSet(); - assertThat(rsaTokenConverter.isPublic()).isTrue(); - assertThat(rsaTokenConverter.getKey()).containsKeys("alg", "value"); - assertThat(rsaTokenConverter.getKey()).containsEntry("alg", "SHA256withRSA"); - } +// @Test +// public void testAccessTokenConverter() throws Exception { +// ResourceLoader resourceLoader = new DefaultResourceLoader(); +// JwtAccessTokenConverter hmacTokenConverter = (JwtAccessTokenConverter) securityConfig.accessTokenConverter("", resourceLoader); +// assertThat(hmacTokenConverter.getKey()).containsKeys("alg", "value"); +// assertThat(hmacTokenConverter.getKey()).containsEntry("alg", "HMACSHA256"); +// assertThat(hmacTokenConverter.getKey().get("value")).hasSize(6); +// JwtAccessTokenConverter hmacTokenConverter2 = (JwtAccessTokenConverter) securityConfig.accessTokenConverter("1234", resourceLoader); +// assertThat(hmacTokenConverter2.getKey()).containsKeys("alg", "value"); +// assertThat(hmacTokenConverter2.getKey()).containsEntry("alg", "HMACSHA256"); +// assertThat(hmacTokenConverter2.getKey().get("value")).hasSize(4); +// JwtAccessTokenConverter rsaTokenConverter = (JwtAccessTokenConverter) securityConfig.accessTokenConverter("classpath:/jwt-signing-key.pem", resourceLoader); +// rsaTokenConverter.afterPropertiesSet(); +// assertThat(rsaTokenConverter.isPublic()).isTrue(); +// assertThat(rsaTokenConverter.getKey()).containsKeys("alg", "value"); +// assertThat(rsaTokenConverter.getKey()).containsEntry("alg", "SHA256withRSA"); +// } /** * Just make coverage happy diff --git a/src/test/java/org/codenergic/theskeleton/core/security/SecurityTest.java b/src/test/java/org/codenergic/theskeleton/core/security/SecurityTest.java index 7ae4af6..1937cc7 100644 --- a/src/test/java/org/codenergic/theskeleton/core/security/SecurityTest.java +++ b/src/test/java/org/codenergic/theskeleton/core/security/SecurityTest.java @@ -20,7 +20,6 @@ import org.codenergic.theskeleton.client.OAuth2ClientService; import org.codenergic.theskeleton.core.security.SecurityTest.SecurityTestConfiguration; -import org.codenergic.theskeleton.user.UserEntity; import org.codenergic.theskeleton.user.UserService; import org.junit.Test; import org.junit.runner.RunWith; @@ -34,8 +33,6 @@ import org.springframework.security.core.Authentication; import org.springframework.security.oauth2.provider.approval.ApprovalStore; import org.springframework.security.oauth2.provider.token.UserAuthenticationConverter; -import org.springframework.social.connect.UsersConnectionRepository; -import org.springframework.social.security.SocialUserDetailsService; import org.springframework.test.context.junit4.SpringRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -105,15 +102,5 @@ public UserService mockUserService() { public OAuth2ClientService mockOAuth2ClientService() { return mock(OAuth2ClientService.class); } - - @Bean - public UsersConnectionRepository usersConnectionRepository() { - return mock(UsersConnectionRepository.class); - } - - @Bean - public SocialUserDetailsService socialUserDetailsService() { - return mock(SocialUserDetailsService.class); - } } } diff --git a/src/test/java/org/codenergic/theskeleton/core/social/SocialConfigTest.java b/src/test/java/org/codenergic/theskeleton/core/social/SocialConfigTest.java deleted file mode 100644 index e592817..0000000 --- a/src/test/java/org/codenergic/theskeleton/core/social/SocialConfigTest.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * * - * http://www.apache.org/licenses/LICENSE-2.0 - * * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.codenergic.theskeleton.core.social; - -import org.codenergic.theskeleton.social.SocialConnectionRepository; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.social.connect.ConnectionFactoryLocator; -import org.springframework.social.connect.UsersConnectionRepository; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = {SocialConfig.class}, webEnvironment = SpringBootTest.WebEnvironment.NONE) -public class SocialConfigTest { - @MockBean - private ConnectionFactoryLocator connectionFactoryLocator; - @MockBean - private SocialConnectionRepository socialConnectionRepository; - @MockBean - private UsersConnectionRepository usersConnectionRepository; - @MockBean - private UserDetailsService userDetailsService; - - @Autowired - private SocialConfig socialConfig; - - @Test - public void initTest() { - // do nothing - } -} diff --git a/src/test/java/org/codenergic/theskeleton/core/social/SocialUsersConnectionServiceTest.java b/src/test/java/org/codenergic/theskeleton/core/social/SocialUsersConnectionServiceTest.java deleted file mode 100644 index 30b9828..0000000 --- a/src/test/java/org/codenergic/theskeleton/core/social/SocialUsersConnectionServiceTest.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * * - * http://www.apache.org/licenses/LICENSE-2.0 - * * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.codenergic.theskeleton.core.social; - -import org.codenergic.theskeleton.social.SocialConnectionEntity; -import org.codenergic.theskeleton.social.SocialConnectionRepository; -import org.codenergic.theskeleton.user.UserEntity; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.springframework.social.connect.Connection; -import org.springframework.social.connect.ConnectionFactoryLocator; -import org.springframework.social.connect.ConnectionKey; - -import java.util.Collections; -import java.util.List; -import java.util.Set; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class SocialUsersConnectionServiceTest { - private static final String PROVIDER_ID = "facebookTest"; - private static final String USER_ID = "userTest"; - - @Mock - private ConnectionFactoryLocator connectionFactoryLocator; - @Mock - private SocialConnectionRepository connectionRepository; - @Mock - private Connection connection; - private SocialUsersConnectionService usersConnectionService; - - private final SocialConnectionEntity dummySocialConnection = new SocialConnectionEntity() - .setProvider(PROVIDER_ID) - .setProviderUserId(USER_ID) - .setDisplayName(USER_ID) - .setProfileUrl("http://profileUrl") - .setImageUrl("http://imageUrl") - .setAccessToken("AccessToken") - .setSecret("s3cr3t") - .setRefreshToken("RefreshToken") - .setExpireTime(0L) - .setUser(new UserEntity().setId("123456")); - - @Before - public void init() { - MockitoAnnotations.initMocks(this); - usersConnectionService = new SocialUsersConnectionService(connectionFactoryLocator, connectionRepository); - } - - @Test - public void testFindUserIdsWithConnection() { - when(connection.getKey()).thenReturn(new ConnectionKey(PROVIDER_ID, USER_ID)); - when(connectionRepository.findByProviderAndProviderUserId(PROVIDER_ID, USER_ID)) - .thenReturn(Collections.singletonList(dummySocialConnection)); - List users = usersConnectionService.findUserIdsWithConnection(connection); - assertThat(users).hasSize(1); - assertThat(users).first().isEqualTo(dummySocialConnection.getUser().getId()); - verify(connection).getKey(); - verify(connectionRepository).findByProviderAndProviderUserId(PROVIDER_ID, USER_ID); - } - - @Test - public void testFindUserIdsConnectedTo() { - Set providerUserIds = Collections.singleton(USER_ID); - when(connectionRepository.findByProviderAndProviderUserIdIn(PROVIDER_ID, providerUserIds)) - .thenReturn(Collections.singletonList(dummySocialConnection)); - Set users = usersConnectionService.findUserIdsConnectedTo(PROVIDER_ID, providerUserIds); - assertThat(users).hasSize(1); - assertThat(users).first().isEqualTo(dummySocialConnection.getUser().getId()); - verify(connectionRepository).findByProviderAndProviderUserIdIn(PROVIDER_ID, providerUserIds); - } - - @Test - public void testCreateConnectionRepository() { - usersConnectionService.createConnectionRepository(USER_ID); - assertThatThrownBy(() -> usersConnectionService.createConnectionRepository(null)) - .isInstanceOf(IllegalArgumentException.class); - } -} diff --git a/src/test/java/org/codenergic/theskeleton/follower/UserFollowerServiceTest.java b/src/test/java/org/codenergic/theskeleton/follower/UserFollowerServiceTest.java index b4472f3..0e08b75 100644 --- a/src/test/java/org/codenergic/theskeleton/follower/UserFollowerServiceTest.java +++ b/src/test/java/org/codenergic/theskeleton/follower/UserFollowerServiceTest.java @@ -28,7 +28,7 @@ public class UserFollowerServiceTest { private List userFollowerEntities; @Before - public void init() throws Exception { + public void init() { MockitoAnnotations.initMocks(this); userFollowerService = new UserFollowerServiceImpl(userFollowerRepository); @@ -43,7 +43,7 @@ public void init() throws Exception { @Test public void testFindUserFollowers() { when(userFollowerRepository.findByUserId(eq("123"), any())).thenReturn(new PageImpl<>(userFollowerEntities)); - Page users = userFollowerService.findUserFollowers("123", new PageRequest(0, 10)); + Page users = userFollowerService.findUserFollowers("123", PageRequest.of(0, 10)); assertThat(users.getTotalElements()).isEqualTo(10); assertThat(users.getContent()).first().hasFieldOrPropertyWithValue("id", "80123"); verify(userFollowerRepository).findByUserId(eq("123"), any()); @@ -52,7 +52,7 @@ public void testFindUserFollowers() { @Test public void testFindUserFollowings() { when(userFollowerRepository.findByFollowerId(eq("123"), any())).thenReturn(new PageImpl<>(userFollowerEntities)); - Page users = userFollowerService.findUserFollowings("123", new PageRequest(0, 10)); + Page users = userFollowerService.findUserFollowings("123", PageRequest.of(0, 10)); assertThat(users.getTotalElements()).isEqualTo(10); assertThat(users.getContent()).first().hasFieldOrPropertyWithValue("id", "0123"); verify(userFollowerRepository).findByFollowerId(eq("123"), any()); diff --git a/src/test/java/org/codenergic/theskeleton/gallery/GalleryServiceTest.java b/src/test/java/org/codenergic/theskeleton/gallery/GalleryServiceTest.java index ee08c3a..6ca258b 100644 --- a/src/test/java/org/codenergic/theskeleton/gallery/GalleryServiceTest.java +++ b/src/test/java/org/codenergic/theskeleton/gallery/GalleryServiceTest.java @@ -51,17 +51,17 @@ public void init() { } @Test - public void testDeleteImages() throws Exception { + public void testDeleteImages() { galleryService.deleteImages("123", "1234", "12345"); - verify(galleryRepository).delete("1234"); - verify(galleryRepository).delete("12345"); + verify(galleryRepository).deleteById("1234"); + verify(galleryRepository).deleteById("12345"); } @Test - public void testFindImageByUser() throws Exception { + public void testFindImageByUser() { when(galleryRepository.findByCreatedByUserIdOrderByIdDesc(eq("1234"), any())) .thenReturn(new PageImpl<>(new ArrayList<>())); - Page result = galleryService.findImageByUser("1234", new PageRequest(0, 10)); + Page result = galleryService.findImageByUser("1234", PageRequest.of(0, 10)); assertThat(result).hasSize(0); assertThat(result.getTotalPages()).isEqualTo(1); verify(galleryRepository).findByCreatedByUserIdOrderByIdDesc(eq("1234"), any()); diff --git a/src/test/java/org/codenergic/theskeleton/post/PostServiceTest.java b/src/test/java/org/codenergic/theskeleton/post/PostServiceTest.java index 8c24c39..31fef96 100644 --- a/src/test/java/org/codenergic/theskeleton/post/PostServiceTest.java +++ b/src/test/java/org/codenergic/theskeleton/post/PostServiceTest.java @@ -65,7 +65,7 @@ public void init() { @Test public void testDeletePost() { postService.deletePost("123"); - verify(postRepository).delete("123"); + verify(postRepository).deleteById("123"); } @Test diff --git a/src/test/java/org/codenergic/theskeleton/privilege/PrivilegeServiceTest.java b/src/test/java/org/codenergic/theskeleton/privilege/PrivilegeServiceTest.java index ab0792c..8fc3d34 100644 --- a/src/test/java/org/codenergic/theskeleton/privilege/PrivilegeServiceTest.java +++ b/src/test/java/org/codenergic/theskeleton/privilege/PrivilegeServiceTest.java @@ -145,7 +145,7 @@ public void testFindPrivileges() { PrivilegeEntity result = new PrivilegeEntity() {{ setId("123"); }}.setName("user_list_read"); Page page = new PageImpl<>(Collections.singletonList(result)); when(privilegeRepository.findAll(any(Pageable.class))).thenReturn(page); - assertThat(privilegeService.findPrivileges(new PageRequest(1, 10))).isEqualTo(page); + assertThat(privilegeService.findPrivileges(PageRequest.of(1, 10))).isEqualTo(page); verify(privilegeRepository).findAll(any(Pageable.class)); when(privilegeRepository.findByNameOrDescriptionStartsWith(anyString(), any())).thenReturn(page); diff --git a/src/test/java/org/codenergic/theskeleton/registration/RegistrationControllerTest.java b/src/test/java/org/codenergic/theskeleton/registration/RegistrationControllerTest.java index 2005c94..eac3adb 100644 --- a/src/test/java/org/codenergic/theskeleton/registration/RegistrationControllerTest.java +++ b/src/test/java/org/codenergic/theskeleton/registration/RegistrationControllerTest.java @@ -10,7 +10,6 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.data.web.config.EnableSpringDataWebSupport; import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.social.connect.web.ProviderSignInUtils; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; @@ -31,8 +30,6 @@ public class RegistrationControllerTest { private RegistrationService registrationService; @MockBean private TokenStoreService tokenStoreService; - @MockBean - private ProviderSignInUtils providerSignInUtils; @Test public void testRegisterUserAlreadyExist() throws Exception { diff --git a/src/test/java/org/codenergic/theskeleton/role/RoleServiceTest.java b/src/test/java/org/codenergic/theskeleton/role/RoleServiceTest.java index 38fd734..48166a3 100644 --- a/src/test/java/org/codenergic/theskeleton/role/RoleServiceTest.java +++ b/src/test/java/org/codenergic/theskeleton/role/RoleServiceTest.java @@ -117,7 +117,7 @@ public void testFindRoles() { RoleEntity result = new RoleEntity() {{ setId("123"); }}.setCode("user"); Page page = new PageImpl<>(Collections.singletonList(result)); when(roleRepository.findByCodeOrDescriptionStartsWith(anyString(), any(Pageable.class))).thenReturn(page); - assertThat(roleService.findRoles("", new PageRequest(1, 10))).isEqualTo(page); + assertThat(roleService.findRoles("", PageRequest.of(1, 10))).isEqualTo(page); verify(roleRepository).findByCodeOrDescriptionStartsWith(anyString(), any(Pageable.class)); } @@ -161,7 +161,6 @@ public void testSaveRole() { public void testUpdateRole() { RoleEntity input = new RoleEntity() {{ setId("123"); }}.setCode("user"); RoleEntity result = new RoleEntity() {{ setId("123"); }}.setCode(UUID.randomUUID().toString()); - when(roleRepository.findOne(anyString())).thenReturn(null); when(roleRepository.findByCode(eq("123"))).thenReturn(Optional.of(result)); when(roleRepository.save(eq(input))).thenReturn(input); assertThat(roleService.updateRole("123", input)).isEqualTo(result); diff --git a/src/test/java/org/codenergic/theskeleton/social/SocialConnectionServiceTest.java b/src/test/java/org/codenergic/theskeleton/social/SocialConnectionServiceTest.java deleted file mode 100644 index 2e517e2..0000000 --- a/src/test/java/org/codenergic/theskeleton/social/SocialConnectionServiceTest.java +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright 2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * * - * http://www.apache.org/licenses/LICENSE-2.0 - * * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.codenergic.theskeleton.social; - -import org.codenergic.theskeleton.user.UserEntity; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.springframework.social.connect.*; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; - -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class SocialConnectionServiceTest { - private static final String PROVIDER_ID = "facebookTest"; - private static final String USER_ID = "userTest"; - private final SocialConnectionEntity dummySocialConnection = new SocialConnectionEntity() - .setProvider(PROVIDER_ID) - .setProviderUserId(USER_ID) - .setDisplayName(USER_ID) - .setProfileUrl("http://profileUrl") - .setImageUrl("http://imageUrl") - .setAccessToken("AccessToken") - .setSecret("s3cr3t") - .setRefreshToken("RefreshToken") - .setExpireTime(0L) - .setUser(new UserEntity().setId("123456")); - private final ConnectionData dummyConnectionData = new ConnectionData(PROVIDER_ID, - USER_ID, - USER_ID, - dummySocialConnection.getProfileUrl(), - dummySocialConnection.getImageUrl(), - dummySocialConnection.getAccessToken(), - dummySocialConnection.getSecret(), - dummySocialConnection.getRefreshToken(), - dummySocialConnection.getExpireTime()); - @Mock - private ConnectionFactory connectionFactory; - @Mock - private ConnectionFactoryLocator connectionFactoryLocator; - @Mock - private SocialConnectionRepository socialConnectionRepository; - private SocialConnectionService socialConnectionService; - - @SuppressWarnings("unchecked") - @Before - public void init() { - MockitoAnnotations.initMocks(this); - when(connectionFactory.getProviderId()).thenReturn(PROVIDER_ID); - when(connectionFactory.createConnection(any())).then(invocation -> { - ConnectionData connectionData = invocation.getArgument(0); - return new DummyConnection(connectionData); - }); - when(connectionFactoryLocator.getConnectionFactory(Object.class)).thenReturn(connectionFactory); - when(connectionFactoryLocator.getConnectionFactory(PROVIDER_ID)).thenReturn(connectionFactory); - socialConnectionService = new SocialConnectionService(USER_ID, socialConnectionRepository, connectionFactoryLocator); - } - - @Test - public void testAddConnection() { - when(socialConnectionRepository.getRank(USER_ID, PROVIDER_ID)).thenReturn(1); - socialConnectionService.addConnection(new DummyConnection(dummyConnectionData)); - verify(socialConnectionRepository).getRank(USER_ID, PROVIDER_ID); - verify(socialConnectionRepository).save(any(SocialConnectionEntity.class)); - } - - @SuppressWarnings("unchecked") - @Test - public void testFindAllConnections() { - when(socialConnectionRepository.findByUserIdOrderByRankAsc(USER_ID)) - .thenReturn(Collections.singletonList(dummySocialConnection)); - MultiValueMap> connections = socialConnectionService.findAllConnections(); - assertThat(connections).containsKey(PROVIDER_ID); - assertThat(connections.get(PROVIDER_ID)).hasSize(1); - assertThat(connections.get(PROVIDER_ID)).first().hasFieldOrPropertyWithValue("profileUrl", dummySocialConnection.getProfileUrl()); - verify(connectionFactory).createConnection(any()); - verify(socialConnectionRepository).findByUserIdOrderByRankAsc(USER_ID); - } - - @Test - public void testFindConnections() { - when(socialConnectionRepository.findByUserIdAndProviderOrderByRankAsc(USER_ID, PROVIDER_ID)) - .thenReturn(Collections.singletonList(dummySocialConnection)); - List> connections = socialConnectionService.findConnections(Object.class); - assertThat(connections).hasSize(1); - assertThat(connections).first().hasFieldOrPropertyWithValue("displayName", dummySocialConnection.getDisplayName()); - verify(connectionFactory).getProviderId(); - verify(connectionFactory).createConnection(any()); - verify(connectionFactoryLocator).getConnectionFactory(Object.class); - verify(socialConnectionRepository).findByUserIdAndProviderOrderByRankAsc(USER_ID, PROVIDER_ID); - } - - @Test - public void testFindConnectionsToUsers() { - assertThatThrownBy(() -> socialConnectionService.findConnectionsToUsers(new LinkedMultiValueMap<>())) - .isInstanceOf(UnsupportedOperationException.class); - } - - @Test - public void testFindPrimaryConnection() { - when(socialConnectionRepository.findByUserIdAndProviderAndRank(USER_ID, PROVIDER_ID, 1)) - .thenReturn(Collections.singletonList(dummySocialConnection)); - Connection conn = socialConnectionService.findPrimaryConnection(Object.class); - assertThat(conn.getKey().getProviderId()).isEqualTo(PROVIDER_ID); - assertThat(conn.getKey().getProviderUserId()).isEqualTo(USER_ID); - conn = socialConnectionService.getPrimaryConnection(Object.class); - assertThat(conn.getKey().getProviderId()).isEqualTo(PROVIDER_ID); - assertThat(conn.getKey().getProviderUserId()).isEqualTo(USER_ID); - verify(connectionFactoryLocator, times(2)).getConnectionFactory(Object.class); - verify(socialConnectionRepository, times(2)).findByUserIdAndProviderAndRank(USER_ID, PROVIDER_ID, 1); - } - - @Test - public void testGetConnection() { - when(socialConnectionRepository.findByUserIdAndProviderAndProviderUserId(USER_ID, PROVIDER_ID, USER_ID)) - .thenReturn(Optional.of(dummySocialConnection)); - Connection conn = socialConnectionService.getConnection(new ConnectionKey(PROVIDER_ID, USER_ID)); - assertThat(conn.getKey().getProviderId()).isEqualTo(PROVIDER_ID); - assertThat(conn.getKey().getProviderUserId()).isEqualTo(USER_ID); - assertThat(conn.getDisplayName()).isEqualTo(dummySocialConnection.getDisplayName()); - conn = socialConnectionService.getConnection(Object.class, USER_ID); - assertThat(conn.getKey().getProviderId()).isEqualTo(PROVIDER_ID); - assertThat(conn.getKey().getProviderUserId()).isEqualTo(USER_ID); - assertThat(conn.getDisplayName()).isEqualTo(dummySocialConnection.getDisplayName()); - verify(connectionFactoryLocator).getConnectionFactory(Object.class); - verify(socialConnectionRepository, times(2)).findByUserIdAndProviderAndProviderUserId(USER_ID, PROVIDER_ID, USER_ID); - } - - @Test - public void testRemoveConnections() { - when(socialConnectionRepository.findByUserIdAndProviderAndProviderUserId(USER_ID, PROVIDER_ID, USER_ID)) - .thenReturn(Optional.of(dummySocialConnection)); - when(socialConnectionRepository.findByUserIdAndProvider(USER_ID, PROVIDER_ID)) - .thenReturn(Collections.singletonList(dummySocialConnection)); - socialConnectionService.removeConnection(new ConnectionKey(PROVIDER_ID, USER_ID)); - socialConnectionService.removeConnections(PROVIDER_ID); - verify(socialConnectionRepository).findByUserIdAndProviderAndProviderUserId(USER_ID, PROVIDER_ID, USER_ID); - verify(socialConnectionRepository).findByUserIdAndProvider(USER_ID, PROVIDER_ID); - verify(socialConnectionRepository).delete(dummySocialConnection); - verify(socialConnectionRepository).delete(Collections.singletonList(dummySocialConnection)); - } - - @Test - public void testSocialUserEntity() { - assertThat(new SocialUserEntity(new UserEntity().setId("123")).getUserId()).isEqualTo("123"); - } - - @Test - public void testUpdateConnection() { - when(socialConnectionRepository.findByUserIdAndProviderAndProviderUserId(USER_ID, PROVIDER_ID, USER_ID)) - .thenReturn(Optional.of(dummySocialConnection)); - socialConnectionService.updateConnection(new DummyConnection(dummyConnectionData)); - verify(socialConnectionRepository).findByUserIdAndProviderAndProviderUserId(USER_ID, PROVIDER_ID, USER_ID); - verify(socialConnectionRepository).save(any(SocialConnectionEntity.class)); - } - - private static class DummyConnection implements Connection { - private final ConnectionData connectionData; - - private DummyConnection(ConnectionData connectionData) { - this.connectionData = connectionData; - } - - @Override - public ConnectionData createData() { - return connectionData; - } - - @Override - public UserProfile fetchUserProfile() { - return null; - } - - @Override - public Object getApi() { - return null; - } - - @Override - public String getDisplayName() { - return connectionData.getDisplayName(); - } - - @Override - public String getImageUrl() { - return connectionData.getImageUrl(); - } - - @Override - public ConnectionKey getKey() { - return new ConnectionKey(connectionData.getProviderId(), connectionData.getProviderUserId()); - } - - @Override - public String getProfileUrl() { - return connectionData.getProfileUrl(); - } - - @Override - public boolean hasExpired() { - return false; - } - - @Override - public void refresh() { - - } - - @Override - public void sync() { - } - - @Override - public boolean test() { - return false; - } - - @Override - public void updateStatus(String message) { - - } - } -} diff --git a/src/test/java/org/codenergic/theskeleton/social/SocialUserServiceTest.java b/src/test/java/org/codenergic/theskeleton/social/SocialUserServiceTest.java deleted file mode 100644 index 9a36e22..0000000 --- a/src/test/java/org/codenergic/theskeleton/social/SocialUserServiceTest.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * * - * http://www.apache.org/licenses/LICENSE-2.0 - * * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.codenergic.theskeleton.social; - -import java.util.Optional; - -import org.codenergic.theskeleton.user.UserEntity; -import org.codenergic.theskeleton.user.UserRepository; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class SocialUserServiceTest { - @Mock - private UserRepository userRepository; - private SocialUserService socialUserService; - - @Before - public void init() { - MockitoAnnotations.initMocks(this); - socialUserService = new SocialUserService(userRepository); - } - - @Test - public void testLoadUserByUserId() { - when(userRepository.findById("123")).thenReturn(Optional.of(new UserEntity())); - socialUserService.loadUserByUserId("123"); - verify(userRepository).findById("123"); - } -} diff --git a/src/test/java/org/codenergic/theskeleton/user/UserSocialRestControllerTest.java b/src/test/java/org/codenergic/theskeleton/user/UserSocialRestControllerTest.java deleted file mode 100644 index 0398b17..0000000 --- a/src/test/java/org/codenergic/theskeleton/user/UserSocialRestControllerTest.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright 2018 original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.codenergic.theskeleton.user; - -import org.codenergic.theskeleton.core.test.EnableRestDocs; -import org.codenergic.theskeleton.core.test.InjectUserDetailsService; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.http.MediaType; -import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.security.test.context.support.WithMockUser; -import org.springframework.social.connect.Connection; -import org.springframework.social.connect.ConnectionData; -import org.springframework.social.connect.ConnectionKey; -import org.springframework.social.connect.ConnectionRepository; -import org.springframework.social.connect.UserProfile; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; -import org.springframework.util.LinkedMultiValueMap; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; - -@RunWith(SpringRunner.class) -@WebMvcTest(controllers = {UserSocialRestController.class}) -@EnableRestDocs -@InjectUserDetailsService -public class UserSocialRestControllerTest { - @MockBean - private ConnectionRepository connectionRepository; - @Autowired - private MockMvc mockMvc; - @Autowired - private ObjectMapper objectMapper; - - private static final String PROVIDER_ID = "facebookTest"; - private final ConnectionData connectionData = new ConnectionData(PROVIDER_ID, - "user123", - "user123", - "http://profileUrl", - "http://imageUrl", - "accessToken", - "s3cr3t", - "refreshToken", - 0L); - private Connection connection = new Connection() { - @Override - public ConnectionKey getKey() { - return new ConnectionKey(connectionData.getProviderId(), connectionData.getProviderUserId()); - } - - @Override - public String getDisplayName() { - return connectionData.getDisplayName(); - } - - @Override - public String getProfileUrl() { - return connectionData.getProfileUrl(); - } - - @Override - public String getImageUrl() { - return connectionData.getImageUrl(); - } - - @Override - public void sync() { - - } - - @Override - public boolean test() { - return false; - } - - @Override - public boolean hasExpired() { - return false; - } - - @Override - public void refresh() { - - } - - @Override - public UserProfile fetchUserProfile() { - return null; - } - - @Override - public void updateStatus(String message) { - - } - - @Override - public Object getApi() { - return null; - } - - @Override - public ConnectionData createData() { - return connectionData; - } - }; - - @Test - @WithMockUser("user123") - public void testFindUserSocialConnections() throws Exception { - LinkedMultiValueMap> connections = new LinkedMultiValueMap<>(); - connections.add(connection.getKey().getProviderId(), connection); - when(connectionRepository.findAllConnections()).thenReturn(connections); - MockHttpServletRequestBuilder request = get("/api/users/user123/socials") - .contentType(MediaType.APPLICATION_JSON); - MockHttpServletResponse response = mockMvc.perform(request) - .andDo(document("user-socials-list")) - .andReturn() - .getResponse(); - assertThat(response.getStatus()).isEqualTo(200); - JsonNode jsonResponse = objectMapper.readTree(response.getContentAsString()); - assertThat(jsonResponse.isObject()).isTrue(); - assertThat(jsonResponse.has(PROVIDER_ID)).isTrue(); - assertThat(jsonResponse.get(PROVIDER_ID).isObject()).isTrue(); - assertThat(jsonResponse.get(PROVIDER_ID).get("imageUrl").textValue()).isEqualTo(connection.getImageUrl()); - verify(connectionRepository).findAllConnections(); - } - - @Test - @WithMockUser("user123") - public void testRemoveUserSocialConnection() throws Exception { - MockHttpServletRequestBuilder request = delete("/api/users/user123/socials") - .content(PROVIDER_ID) - .contentType(MediaType.APPLICATION_JSON); - MockHttpServletResponse response = mockMvc.perform(request) - .andDo(document("user-socials-remove")) - .andReturn() - .getResponse(); - assertThat(response.getStatus()).isEqualTo(200); - verify(connectionRepository).removeConnections(PROVIDER_ID); - } -} From f8afc2f067fa4c9f31b7efaca03070560776d75b Mon Sep 17 00:00:00 2001 From: dianw Date: Sat, 25 May 2019 20:43:19 +0700 Subject: [PATCH 2/5] Merge branch 'master' into spring-boot-2 --- .../org/codenergic/theskeleton/core/web/WebSocketConfig.java | 4 ++-- .../java/org/codenergic/theskeleton/post/PostServiceImpl.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/codenergic/theskeleton/core/web/WebSocketConfig.java b/src/main/java/org/codenergic/theskeleton/core/web/WebSocketConfig.java index be41f31..54bc8e0 100644 --- a/src/main/java/org/codenergic/theskeleton/core/web/WebSocketConfig.java +++ b/src/main/java/org/codenergic/theskeleton/core/web/WebSocketConfig.java @@ -25,13 +25,13 @@ import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.messaging.simp.config.MessageBrokerRegistry; import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer; import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; import org.springframework.web.socket.config.annotation.StompEndpointRegistry; +import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; @Configuration @EnableWebSocketMessageBroker -public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { +public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry registry) { registry.enableSimpleBroker("/topic"); diff --git a/src/main/java/org/codenergic/theskeleton/post/PostServiceImpl.java b/src/main/java/org/codenergic/theskeleton/post/PostServiceImpl.java index 5107d74..6d34576 100644 --- a/src/main/java/org/codenergic/theskeleton/post/PostServiceImpl.java +++ b/src/main/java/org/codenergic/theskeleton/post/PostServiceImpl.java @@ -36,7 +36,7 @@ public PostServiceImpl(PostRepository postRepository, PostFollowingRepository po @Override public void deletePost(String id) { - postRepository.delete(id); + postRepository.deleteById(id); } @Override From e58d11cdcef602847e163c3f8d7cef0c9f54f13a Mon Sep 17 00:00:00 2001 From: dianw Date: Fri, 13 Sep 2019 23:54:49 +0700 Subject: [PATCH 3/5] Cleanup --- .../theskeleton/registration/RegistrationController.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/org/codenergic/theskeleton/registration/RegistrationController.java b/src/main/java/org/codenergic/theskeleton/registration/RegistrationController.java index a7f995b..461be97 100644 --- a/src/main/java/org/codenergic/theskeleton/registration/RegistrationController.java +++ b/src/main/java/org/codenergic/theskeleton/registration/RegistrationController.java @@ -17,8 +17,6 @@ import javax.validation.Valid; -import org.codenergic.theskeleton.tokenstore.TokenStoreService; -import org.codenergic.theskeleton.user.UserEntity; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; @@ -36,11 +34,9 @@ public class RegistrationController { private static final String REGISTRATION_ACTIVATION = "registration_activation"; private final RegistrationService registrationService; - private final TokenStoreService tokenStoreService; - public RegistrationController(RegistrationService registrationService, TokenStoreService tokenStoreService) { + public RegistrationController(RegistrationService registrationService) { this.registrationService = registrationService; - this.tokenStoreService = tokenStoreService; } @GetMapping From 14bec414c2d889199c381a3497fbaedef1ed5af3 Mon Sep 17 00:00:00 2001 From: Dian Aditya Date: Sat, 6 Feb 2021 00:49:11 +0700 Subject: [PATCH 4/5] Upgrade spring-boot version to 2.4.2 --- pom.xml | 36 ++++++++------ .../core/data/S3BucketProperties.java | 10 ++++ .../theskeleton/core/data/S3ClientConfig.java | 49 +++++-------------- .../core/data/S3ClientProperties.java | 31 ++++++++++++ .../theskeleton/core/data/S3ClientUtils.java | 10 ++++ .../core/security/WebSecurityConfig.java | 10 ++-- .../theskeleton/gallery/GalleryEntity.java | 11 +++++ .../gallery/GalleryRestController.java | 1 + .../gallery/GalleryServiceImpl.java | 30 ++++++------ .../theskeleton/user/UserMapper.java | 2 +- .../theskeleton/user/UserRestController.java | 2 +- .../theskeleton/user/UserService.java | 2 +- .../theskeleton/user/UserServiceImpl.java | 24 +++++++-- .../OAuth2ClientRestControllerTest.java | 2 +- .../core/data/S3ClientConfigTest.java | 21 ++++---- .../core/test/EnableSecurityConfig.java | 32 ++++++++++++ .../core/test/InjectUserDetailsService.java | 1 + .../gallery/GalleryServiceTest.java | 19 ++++--- .../PrivilegeRestControllerTest.java | 2 +- .../RolePrivilegeRestControllerTest.java | 2 +- .../RegistrationControllerTest.java | 2 +- .../RegistrationRestControllerTest.java | 3 +- .../role/RoleRestControllerTest.java | 2 +- .../role/UserRoleRestControllerTest.java | 2 +- .../user/UserRestControllerTest.java | 9 ++-- .../theskeleton/user/UserServiceTest.java | 20 ++++---- 26 files changed, 220 insertions(+), 115 deletions(-) create mode 100644 src/main/java/org/codenergic/theskeleton/core/data/S3BucketProperties.java create mode 100644 src/main/java/org/codenergic/theskeleton/core/data/S3ClientProperties.java create mode 100644 src/main/java/org/codenergic/theskeleton/core/data/S3ClientUtils.java create mode 100644 src/test/java/org/codenergic/theskeleton/core/test/EnableSecurityConfig.java diff --git a/pom.xml b/pom.xml index 00256f2..cd2ae43 100644 --- a/pom.xml +++ b/pom.xml @@ -24,20 +24,20 @@ 4.1.0 - 3.8.1 + 3.11 1.1.0 - 26.0-jre - 2.7.1 - 0.8.2 - 1.3.0.Beta1 - 3.8.0 - 2.2.5 - 3.1.0 - 5.0.1 - 2.0.5.RELEASE + 30.1-jre + 2.8.8 + 0.8.6 + 1.4.1.Final + 3.8.1 + 4.0.3 + 3.2.0 + 8.0.3 + 2.4.2 0.6.3 - 2.0.2.RELEASE - 2.0.5.RELEASE + 2.0.5.RELEASE + 2.5.0.RELEASE UTF-8 UTF-8 1.8 @@ -84,7 +84,7 @@ org.springframework.security.oauth.boot spring-security-oauth2-autoconfigure - ${spring-security-oauth-version} + ${spring-boot.version} org.springframework.session @@ -135,6 +135,10 @@ org.hibernate hibernate-ehcache + + org.hibernate.validator + hibernate-validator + org.mariadb.jdbc mariadb-java-client @@ -180,6 +184,10 @@ org.springframework.boot spring-boot-starter-data-redis + + org.hibernate + hibernate-validator + @@ -235,7 +243,7 @@ org.mapstruct - mapstruct-jdk8 + mapstruct ${mapstruct.version} diff --git a/src/main/java/org/codenergic/theskeleton/core/data/S3BucketProperties.java b/src/main/java/org/codenergic/theskeleton/core/data/S3BucketProperties.java new file mode 100644 index 0000000..92f31c8 --- /dev/null +++ b/src/main/java/org/codenergic/theskeleton/core/data/S3BucketProperties.java @@ -0,0 +1,10 @@ +package org.codenergic.theskeleton.core.data; + +public class S3BucketProperties { + String name; + + public S3BucketProperties setName(String name) { + this.name = name; + return this; + } +} diff --git a/src/main/java/org/codenergic/theskeleton/core/data/S3ClientConfig.java b/src/main/java/org/codenergic/theskeleton/core/data/S3ClientConfig.java index b453303..2249e1e 100644 --- a/src/main/java/org/codenergic/theskeleton/core/data/S3ClientConfig.java +++ b/src/main/java/org/codenergic/theskeleton/core/data/S3ClientConfig.java @@ -15,7 +15,8 @@ */ package org.codenergic.theskeleton.core.data; -import java.util.ArrayList; +import java.net.MalformedURLException; +import java.net.URI; import java.util.List; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; @@ -28,9 +29,9 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import io.minio.BucketExistsArgs; +import io.minio.MakeBucketArgs; import io.minio.MinioClient; -import io.minio.errors.InvalidEndpointException; -import io.minio.errors.InvalidPortException; @Configuration class S3ClientConfig { @@ -42,9 +43,9 @@ public ScheduledFuture> createBuckets(MinioClient minioClient, Sche .peek(bucket -> logger.info("Checking bucket [{}]", bucket.name)) .peek(bucket -> { try { - if (!minioClient.bucketExists(bucket.name)) { + if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucket.name).build())) { logger.info("Bucket doesn't exists, creating one"); - minioClient.makeBucket(bucket.name); + minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucket.name).build()); logger.info("Bucket created"); } else { logger.info("Bucket already exists"); @@ -58,8 +59,11 @@ public ScheduledFuture> createBuckets(MinioClient minioClient, Sche } @Bean - public MinioClient s3Client(S3ClientProperties clientProps) throws InvalidEndpointException, InvalidPortException { - return new MinioClient(clientProps.endpoint, clientProps.accessKey, clientProps.secretKey); + public MinioClient s3Client(S3ClientProperties clientProps) throws MalformedURLException { + return MinioClient.builder() + .endpoint(URI.create(clientProps.endpoint).toURL()) + .credentials(clientProps.accessKey, clientProps.secretKey) + .build(); } @Bean @@ -68,35 +72,4 @@ public S3ClientProperties s3ClientProperties() { return new S3ClientProperties(); } - public static class S3ClientProperties { - private String accessKey; - private List buckets = new ArrayList<>(); - private String endpoint; - private String secretKey; - - public List getBuckets() { - return buckets; - } - - public void setAccessKey(String accessKey) { - this.accessKey = accessKey; - } - - public void setEndpoint(String endpoint) { - this.endpoint = endpoint; - } - - public void setSecretKey(String secretKey) { - this.secretKey = secretKey; - } - } - - public static class S3BucketProperties { - private String name; - - public S3BucketProperties setName(String name) { - this.name = name; - return this; - } - } } diff --git a/src/main/java/org/codenergic/theskeleton/core/data/S3ClientProperties.java b/src/main/java/org/codenergic/theskeleton/core/data/S3ClientProperties.java new file mode 100644 index 0000000..2e8a6f3 --- /dev/null +++ b/src/main/java/org/codenergic/theskeleton/core/data/S3ClientProperties.java @@ -0,0 +1,31 @@ +package org.codenergic.theskeleton.core.data; + +import java.util.ArrayList; +import java.util.List; + +public class S3ClientProperties { + String accessKey; + List buckets = new ArrayList<>(); + String endpoint; + String secretKey; + + public List getBuckets() { + return buckets; + } + + public void setAccessKey(String accessKey) { + this.accessKey = accessKey; + } + + public void setEndpoint(String endpoint) { + this.endpoint = endpoint; + } + + public void setSecretKey(String secretKey) { + this.secretKey = secretKey; + } + + public String getEndpoint() { + return endpoint; + } +} diff --git a/src/main/java/org/codenergic/theskeleton/core/data/S3ClientUtils.java b/src/main/java/org/codenergic/theskeleton/core/data/S3ClientUtils.java new file mode 100644 index 0000000..67c9d18 --- /dev/null +++ b/src/main/java/org/codenergic/theskeleton/core/data/S3ClientUtils.java @@ -0,0 +1,10 @@ +package org.codenergic.theskeleton.core.data; + +import org.apache.commons.lang3.StringUtils; + +public final class S3ClientUtils { + public static String getObjectUrl(S3ClientProperties properties, String bucket, String objectName) { + return StringUtils.join(properties.getEndpoint(), "/", bucket, "/", objectName); + } + +} diff --git a/src/main/java/org/codenergic/theskeleton/core/security/WebSecurityConfig.java b/src/main/java/org/codenergic/theskeleton/core/security/WebSecurityConfig.java index 4918057..f3c10c9 100644 --- a/src/main/java/org/codenergic/theskeleton/core/security/WebSecurityConfig.java +++ b/src/main/java/org/codenergic/theskeleton/core/security/WebSecurityConfig.java @@ -18,7 +18,6 @@ import java.util.Arrays; import java.util.Collections; -import org.codenergic.theskeleton.user.UserService; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; @@ -32,6 +31,7 @@ import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.core.session.SessionRegistry; +import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.authentication.RememberMeServices; import org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler; @@ -45,12 +45,12 @@ @EnableGlobalMethodSecurity(prePostEnabled = true) @ConditionalOnWebApplication public class WebSecurityConfig extends WebSecurityConfigurerAdapter { - private final UserService userService; + private final UserDetailsService userService; private final PasswordEncoder passwordEncoder; private final RememberMeServices rememberMeServices; private final SessionRegistry sessionRegistry; - public WebSecurityConfig(UserService userService, PasswordEncoder passwordEncoder, + public WebSecurityConfig(UserDetailsService userService, PasswordEncoder passwordEncoder, RememberMeServices rememberMeServices, SessionRegistry sessionRegistry) { this.userService = userService; this.passwordEncoder = passwordEncoder; @@ -109,7 +109,7 @@ protected void configure(HttpSecurity http) throws Exception { * See explanation here */ @Bean - public FilterRegistrationBean corsFilterBean() { + public FilterRegistrationBean corsFilterBean() { final CorsConfiguration configuration = new CorsConfiguration(); configuration.setAllowedOrigins(Collections.singletonList("*")); configuration.setAllowedMethods(Arrays.asList("HEAD", "GET", "POST", "PUT", "DELETE", "PATCH")); @@ -121,7 +121,7 @@ public FilterRegistrationBean corsFilterBean() { configuration.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type")); final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); - FilterRegistrationBean corsFilter = new FilterRegistrationBean<>(new CorsFilter(source)); + FilterRegistrationBean corsFilter = new FilterRegistrationBean<>(new CorsFilter(source)); corsFilter.setOrder(Ordered.HIGHEST_PRECEDENCE); return corsFilter; } diff --git a/src/main/java/org/codenergic/theskeleton/gallery/GalleryEntity.java b/src/main/java/org/codenergic/theskeleton/gallery/GalleryEntity.java index f1b55cd..ce7bbaf 100644 --- a/src/main/java/org/codenergic/theskeleton/gallery/GalleryEntity.java +++ b/src/main/java/org/codenergic/theskeleton/gallery/GalleryEntity.java @@ -33,6 +33,8 @@ public class GalleryEntity extends AbstractAuditingEntity { private transient InputStream image; @Transient private String format; + @Transient + private long size; public String getFormat() { return format; @@ -60,4 +62,13 @@ public GalleryEntity setImageUrl(String imageUrl) { this.imageUrl = imageUrl; return this; } + + public long getSize() { + return size; + } + + public GalleryEntity setSize(long size) { + this.size = size; + return this; + } } diff --git a/src/main/java/org/codenergic/theskeleton/gallery/GalleryRestController.java b/src/main/java/org/codenergic/theskeleton/gallery/GalleryRestController.java index 82927ad..868b4b7 100644 --- a/src/main/java/org/codenergic/theskeleton/gallery/GalleryRestController.java +++ b/src/main/java/org/codenergic/theskeleton/gallery/GalleryRestController.java @@ -50,6 +50,7 @@ public GalleryRestData saveImage(@AuthenticationPrincipal UserEntity userEntity, try (InputStream inputStream = request.getInputStream()) { GalleryEntity gallery = galleryService.saveImage(userEntity.getId(), new GalleryEntity() .setImage(inputStream) + .setSize(request.getContentLengthLong()) .setFormat(request.getContentType())); return galleryMapper.toGalleryData(gallery); } diff --git a/src/main/java/org/codenergic/theskeleton/gallery/GalleryServiceImpl.java b/src/main/java/org/codenergic/theskeleton/gallery/GalleryServiceImpl.java index d2af37f..ca4a051 100644 --- a/src/main/java/org/codenergic/theskeleton/gallery/GalleryServiceImpl.java +++ b/src/main/java/org/codenergic/theskeleton/gallery/GalleryServiceImpl.java @@ -15,26 +15,20 @@ */ package org.codenergic.theskeleton.gallery; -import java.io.IOException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; import java.time.Instant; import java.util.UUID; import org.apache.commons.lang3.StringUtils; +import org.codenergic.theskeleton.core.data.S3ClientProperties; +import org.codenergic.theskeleton.core.data.S3ClientUtils; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import org.xmlpull.v1.XmlPullParserException; import io.minio.MinioClient; -import io.minio.errors.ErrorResponseException; -import io.minio.errors.InsufficientDataException; -import io.minio.errors.InternalException; -import io.minio.errors.InvalidArgumentException; -import io.minio.errors.InvalidBucketNameException; -import io.minio.errors.NoResponseException; +import io.minio.ObjectWriteResponse; +import io.minio.PutObjectArgs; @Service @Transactional(readOnly = true) @@ -42,10 +36,12 @@ class GalleryServiceImpl implements GalleryService { private static final String GALLERY_BUCKET_NAME = "galleries"; private final GalleryRepository galleryRepository; private final MinioClient minioClient; + private final S3ClientProperties s3ClientProperties; - public GalleryServiceImpl(GalleryRepository galleryRepository, MinioClient minioClient) { + public GalleryServiceImpl(GalleryRepository galleryRepository, MinioClient minioClient, S3ClientProperties s3ClientProperties) { this.galleryRepository = galleryRepository; this.minioClient = minioClient; + this.s3ClientProperties = s3ClientProperties; } @Override @@ -69,10 +65,16 @@ public GalleryEntity saveImage(String userId, GalleryEntity image) throws Except return galleryRepository.save(image); } - private String saveImageToS3(String userId, GalleryEntity image) throws InvalidBucketNameException, NoSuchAlgorithmException, InsufficientDataException, IOException, InvalidKeyException, NoResponseException, XmlPullParserException, ErrorResponseException, InternalException, InvalidArgumentException { + private String saveImageToS3(String userId, GalleryEntity image) throws Exception { String imageObjectName = StringUtils.join(userId, "/", Long.toHexString(Instant.now().toEpochMilli()), "-", UUID.randomUUID().toString()); - minioClient.putObject(GALLERY_BUCKET_NAME, imageObjectName, image.getImage(), image.getFormat()); - return minioClient.getObjectUrl(GALLERY_BUCKET_NAME, imageObjectName); + PutObjectArgs putObjectArgs = PutObjectArgs.builder() + .bucket(GALLERY_BUCKET_NAME) + .object(imageObjectName) + .contentType(image.getFormat()) + .stream(image.getImage(), image.getSize(), -1) + .build(); + ObjectWriteResponse resp = minioClient.putObject(putObjectArgs); + return S3ClientUtils.getObjectUrl(s3ClientProperties, resp.bucket(), resp.object()); } } diff --git a/src/main/java/org/codenergic/theskeleton/user/UserMapper.java b/src/main/java/org/codenergic/theskeleton/user/UserMapper.java index f72adcc..d2c5c1b 100644 --- a/src/main/java/org/codenergic/theskeleton/user/UserMapper.java +++ b/src/main/java/org/codenergic/theskeleton/user/UserMapper.java @@ -30,7 +30,7 @@ static UserMapper newInstance() { UserEntity toUser(UserRestData userData); @Mapping(target = "authorities", ignore = true) - @Mapping(target = "nonLocked", source = "accountNonLocked") + @Mapping(target = "isNonLocked", source = "accountNonLocked") @Mapping(target = "password", ignore = true) UserRestData toUserData(UserEntity user); } diff --git a/src/main/java/org/codenergic/theskeleton/user/UserRestController.java b/src/main/java/org/codenergic/theskeleton/user/UserRestController.java index 11e2aa3..ca5e1d2 100644 --- a/src/main/java/org/codenergic/theskeleton/user/UserRestController.java +++ b/src/main/java/org/codenergic/theskeleton/user/UserRestController.java @@ -141,7 +141,7 @@ public UserRestData updateUserPassword(@User.Inject User user, @RequestBody Map< @PutMapping(path = "/{username}/picture", consumes = "image/*") public UserRestData updateUserPicture(@User.Inject User user, HttpServletRequest request) throws Exception { try (InputStream image = request.getInputStream()) { - UserEntity u = userService.updateUserPicture(user.getUsername(), image, request.getContentType()); + UserEntity u = userService.updateUserPicture(user.getUsername(), image, request.getContentType(), request.getContentLengthLong()); return userMapper.toUserData(u); } } diff --git a/src/main/java/org/codenergic/theskeleton/user/UserService.java b/src/main/java/org/codenergic/theskeleton/user/UserService.java index 9e0fa81..67030c5 100644 --- a/src/main/java/org/codenergic/theskeleton/user/UserService.java +++ b/src/main/java/org/codenergic/theskeleton/user/UserService.java @@ -74,5 +74,5 @@ public interface UserService extends UserDetailsService { UserEntity updateUserPassword(@NotNull String username, @NotNull String rawPassword); @PreAuthorize("isAuthenticated() and principal.username == #username") - UserEntity updateUserPicture(String username, InputStream image, String contentType) throws Exception; + UserEntity updateUserPicture(String username, InputStream image, String contentType, long contentLength) throws Exception; } diff --git a/src/main/java/org/codenergic/theskeleton/user/UserServiceImpl.java b/src/main/java/org/codenergic/theskeleton/user/UserServiceImpl.java index d0c25ff..c7891c4 100644 --- a/src/main/java/org/codenergic/theskeleton/user/UserServiceImpl.java +++ b/src/main/java/org/codenergic/theskeleton/user/UserServiceImpl.java @@ -33,6 +33,8 @@ import javax.validation.constraints.NotNull; import org.apache.commons.lang3.StringUtils; +import org.codenergic.theskeleton.core.data.S3ClientProperties; +import org.codenergic.theskeleton.core.data.S3ClientUtils; import org.codenergic.theskeleton.core.security.User; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -46,6 +48,8 @@ import org.springframework.transaction.annotation.Transactional; import io.minio.MinioClient; +import io.minio.ObjectWriteResponse; +import io.minio.PutObjectArgs; @Service @Transactional(readOnly = true) @@ -57,16 +61,18 @@ class UserServiceImpl implements UserService { private final UserAuthorityService userAuthorityService; private final UserOAuth2ClientApprovalRepository clientApprovalRepository; private final SessionRegistry sessionRegistry; + private final S3ClientProperties s3ClientProperties; public UserServiceImpl(MinioClient minioClient, PasswordEncoder passwordEncoder, UserRepository userRepository, UserAuthorityService userAuthorityService, UserOAuth2ClientApprovalRepository clientApprovalRepository, - SessionRegistry sessionRegistry) { + SessionRegistry sessionRegistry, S3ClientProperties s3ClientProperties) { this.minioClient = minioClient; this.passwordEncoder = passwordEncoder; this.userRepository = userRepository; this.userAuthorityService = userAuthorityService; this.clientApprovalRepository = clientApprovalRepository; this.sessionRegistry = sessionRegistry; + this.s3ClientProperties = s3ClientProperties; } @Override @@ -209,13 +215,23 @@ public UserEntity updateUserPassword(String username, String rawPassword) { @Override @Transactional - public UserEntity updateUserPicture(String username, InputStream image, String contentType) throws Exception { + public UserEntity updateUserPicture(String username, InputStream image, String contentType, long contentLength) throws Exception { UserEntity user = findUserByUsername(username) .orElseThrow(() -> new UsernameNotFoundException(username)); + String imageObjectName = StringUtils.join(user.getId(), "/", Long.toHexString(Instant.now().toEpochMilli()), "-", UUID.randomUUID().toString()); - minioClient.putObject(PICTURE_BUCKET_NAME, imageObjectName, image, contentType); - user.setPictureUrl(minioClient.getObjectUrl(PICTURE_BUCKET_NAME, imageObjectName)); + + PutObjectArgs putObjectArgs = PutObjectArgs.builder() + .bucket(PICTURE_BUCKET_NAME) + .object(imageObjectName) + .contentType(contentType) + .stream(image, contentLength, -1) + .build(); + ObjectWriteResponse resp = minioClient.putObject(putObjectArgs); + String pictureUrl = S3ClientUtils.getObjectUrl(s3ClientProperties, resp.bucket(), resp.object()); + user.setPictureUrl(pictureUrl); + return user; } } diff --git a/src/test/java/org/codenergic/theskeleton/client/OAuth2ClientRestControllerTest.java b/src/test/java/org/codenergic/theskeleton/client/OAuth2ClientRestControllerTest.java index f5d358d..9dfed6d 100644 --- a/src/test/java/org/codenergic/theskeleton/client/OAuth2ClientRestControllerTest.java +++ b/src/test/java/org/codenergic/theskeleton/client/OAuth2ClientRestControllerTest.java @@ -56,7 +56,7 @@ @RunWith(SpringRunner.class) @EnableSpringDataWebSupport -@WebMvcTest(controllers = {OAuth2ClientRestController.class}, secure = false) +@WebMvcTest(controllers = {OAuth2ClientRestController.class}) @EnableRestDocs @InjectUserDetailsService public class OAuth2ClientRestControllerTest { diff --git a/src/test/java/org/codenergic/theskeleton/core/data/S3ClientConfigTest.java b/src/test/java/org/codenergic/theskeleton/core/data/S3ClientConfigTest.java index a8fc021..548d4e1 100644 --- a/src/test/java/org/codenergic/theskeleton/core/data/S3ClientConfigTest.java +++ b/src/test/java/org/codenergic/theskeleton/core/data/S3ClientConfigTest.java @@ -26,20 +26,21 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import io.minio.BucketExistsArgs; +import io.minio.MakeBucketArgs; import io.minio.MinioClient; -import io.minio.errors.InvalidBucketNameException; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; public class S3ClientConfigTest { - private S3ClientConfig s3ClientConfig = new S3ClientConfig(); - private S3ClientConfig.S3ClientProperties s3ClientProperties = new S3ClientConfig.S3ClientProperties(); + private final S3ClientConfig s3ClientConfig = new S3ClientConfig(); + private final S3ClientProperties s3ClientProperties = new S3ClientProperties(); + @Mock private MinioClient minioClient; @Mock @@ -52,7 +53,7 @@ public void init() { s3ClientProperties.setSecretKey(""); s3ClientProperties.setEndpoint(""); Stream.of("test1", "test2").forEach(bucketName -> { - S3ClientConfig.S3BucketProperties bucketProperties = new S3ClientConfig.S3BucketProperties(); + S3BucketProperties bucketProperties = new S3BucketProperties(); bucketProperties.setName(bucketName); s3ClientProperties.getBuckets().add(bucketProperties); }); @@ -67,13 +68,13 @@ public void testCreateBucket() throws Exception { callable.call(); return null; }); - when(minioClient.bucketExists(eq("test1"))).thenReturn(true); - when(minioClient.bucketExists(eq("test2"))).thenReturn(false); + when(minioClient.bucketExists(eq(BucketExistsArgs.builder().bucket("test1").build()))).thenReturn(true); + when(minioClient.bucketExists(eq(BucketExistsArgs.builder().bucket("test2").build()))).thenReturn(false); s3ClientConfig.createBuckets(minioClient, executorService, s3ClientProperties); - verify(minioClient, times(2)).bucketExists(anyString()); - verify(minioClient).makeBucket(eq("test2")); + verify(minioClient, times(2)).bucketExists(any()); + verify(minioClient).makeBucket(eq(MakeBucketArgs.builder().bucket("test2").build())); verify(executorService).schedule(argumentCaptor.capture(), anyLong(), any()); - when(minioClient.bucketExists(anyString())).thenThrow(InvalidBucketNameException.class); + when(minioClient.bucketExists(any())).thenThrow(RuntimeException.class); s3ClientConfig.createBuckets(minioClient, executorService, s3ClientProperties); } } diff --git a/src/test/java/org/codenergic/theskeleton/core/test/EnableSecurityConfig.java b/src/test/java/org/codenergic/theskeleton/core/test/EnableSecurityConfig.java new file mode 100644 index 0000000..b3b4d44 --- /dev/null +++ b/src/test/java/org/codenergic/theskeleton/core/test/EnableSecurityConfig.java @@ -0,0 +1,32 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.codenergic.theskeleton.core.test; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.codenergic.theskeleton.core.security.SecurityConfig; +import org.codenergic.theskeleton.core.security.WebSessionConfig; +import org.springframework.context.annotation.Import; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@Import({SecurityConfig.class, WebSessionConfig.class}) +public @interface EnableSecurityConfig { +} diff --git a/src/test/java/org/codenergic/theskeleton/core/test/InjectUserDetailsService.java b/src/test/java/org/codenergic/theskeleton/core/test/InjectUserDetailsService.java index 69e1111..0b8e885 100644 --- a/src/test/java/org/codenergic/theskeleton/core/test/InjectUserDetailsService.java +++ b/src/test/java/org/codenergic/theskeleton/core/test/InjectUserDetailsService.java @@ -25,6 +25,7 @@ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) +@EnableSecurityConfig @Import({TestSecurityConfig.class}) public @interface InjectUserDetailsService { } diff --git a/src/test/java/org/codenergic/theskeleton/gallery/GalleryServiceTest.java b/src/test/java/org/codenergic/theskeleton/gallery/GalleryServiceTest.java index 7a6fb80..3f4fd6f 100644 --- a/src/test/java/org/codenergic/theskeleton/gallery/GalleryServiceTest.java +++ b/src/test/java/org/codenergic/theskeleton/gallery/GalleryServiceTest.java @@ -16,27 +16,30 @@ package org.codenergic.theskeleton.gallery; -import io.minio.MinioClient; +import java.io.ByteArrayInputStream; +import java.util.ArrayList; +import org.codenergic.theskeleton.core.data.S3ClientProperties; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.mockito.junit.MockitoJUnitRunner; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.util.ArrayList; +import io.minio.MinioClient; +import io.minio.ObjectWriteResponse; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +@RunWith(MockitoJUnitRunner.class) public class GalleryServiceTest { @Mock private GalleryRepository galleryRepository; @@ -47,7 +50,7 @@ public class GalleryServiceTest { @Before public void init() { MockitoAnnotations.initMocks(this); - galleryService = new GalleryServiceImpl(galleryRepository, minioClient); + galleryService = new GalleryServiceImpl(galleryRepository, minioClient, new S3ClientProperties()); } @Test @@ -69,11 +72,11 @@ public void testFindImageByUser() { @Test public void testSaveImage() throws Exception { + when(minioClient.putObject(any())).thenReturn(new ObjectWriteResponse(null, "bucket", "region", "object", "etag", "version")); galleryService.saveImage("12345", new GalleryEntity() .setFormat("image/png") .setImage(new ByteArrayInputStream(new byte[0]))); - verify(minioClient).putObject(anyString(), anyString(), any(InputStream.class), eq("image/png")); - verify(minioClient).getObjectUrl(anyString(), anyString()); + verify(minioClient).putObject(any()); } } diff --git a/src/test/java/org/codenergic/theskeleton/privilege/PrivilegeRestControllerTest.java b/src/test/java/org/codenergic/theskeleton/privilege/PrivilegeRestControllerTest.java index a2875cd..dccc994 100644 --- a/src/test/java/org/codenergic/theskeleton/privilege/PrivilegeRestControllerTest.java +++ b/src/test/java/org/codenergic/theskeleton/privilege/PrivilegeRestControllerTest.java @@ -48,7 +48,7 @@ @RunWith(SpringRunner.class) @EnableSpringDataWebSupport -@WebMvcTest(controllers = { PrivilegeRestController.class }, secure = false) +@WebMvcTest(controllers = { PrivilegeRestController.class }) @EnableRestDocs @InjectUserDetailsService public class PrivilegeRestControllerTest { diff --git a/src/test/java/org/codenergic/theskeleton/privilege/RolePrivilegeRestControllerTest.java b/src/test/java/org/codenergic/theskeleton/privilege/RolePrivilegeRestControllerTest.java index 8bdf845..c317ea2 100644 --- a/src/test/java/org/codenergic/theskeleton/privilege/RolePrivilegeRestControllerTest.java +++ b/src/test/java/org/codenergic/theskeleton/privilege/RolePrivilegeRestControllerTest.java @@ -50,7 +50,7 @@ @RunWith(SpringRunner.class) @EnableSpringDataWebSupport -@WebMvcTest(controllers = { RolePrivilegeRestController.class }, secure = false) +@WebMvcTest(controllers = { RolePrivilegeRestController.class }) @EnableRestDocs @InjectUserDetailsService public class RolePrivilegeRestControllerTest { diff --git a/src/test/java/org/codenergic/theskeleton/registration/RegistrationControllerTest.java b/src/test/java/org/codenergic/theskeleton/registration/RegistrationControllerTest.java index eac3adb..42b03aa 100644 --- a/src/test/java/org/codenergic/theskeleton/registration/RegistrationControllerTest.java +++ b/src/test/java/org/codenergic/theskeleton/registration/RegistrationControllerTest.java @@ -21,7 +21,7 @@ @RunWith(SpringRunner.class) @EnableSpringDataWebSupport -@WebMvcTest(controllers = {RegistrationController.class}, secure = false) +@WebMvcTest(controllers = {RegistrationController.class}) @InjectUserDetailsService public class RegistrationControllerTest { @Autowired diff --git a/src/test/java/org/codenergic/theskeleton/registration/RegistrationRestControllerTest.java b/src/test/java/org/codenergic/theskeleton/registration/RegistrationRestControllerTest.java index 2e0fb9f..1858a17 100644 --- a/src/test/java/org/codenergic/theskeleton/registration/RegistrationRestControllerTest.java +++ b/src/test/java/org/codenergic/theskeleton/registration/RegistrationRestControllerTest.java @@ -30,6 +30,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.data.web.config.EnableSpringDataWebSupport; @@ -43,7 +44,7 @@ @RunWith(SpringRunner.class) @EnableSpringDataWebSupport -@WebMvcTest(controllers = {RegistrationRestController.class}, secure = false) +@WebMvcTest(controllers = {RegistrationRestController.class}) @EnableRestDocs @InjectUserDetailsService public class RegistrationRestControllerTest { diff --git a/src/test/java/org/codenergic/theskeleton/role/RoleRestControllerTest.java b/src/test/java/org/codenergic/theskeleton/role/RoleRestControllerTest.java index 33ecade..8f2dd20 100644 --- a/src/test/java/org/codenergic/theskeleton/role/RoleRestControllerTest.java +++ b/src/test/java/org/codenergic/theskeleton/role/RoleRestControllerTest.java @@ -54,7 +54,7 @@ @RunWith(SpringRunner.class) @EnableSpringDataWebSupport -@WebMvcTest(controllers = { RoleRestController.class }, secure = false) +@WebMvcTest(controllers = { RoleRestController.class }) @EnableRestDocs @InjectUserDetailsService public class RoleRestControllerTest { diff --git a/src/test/java/org/codenergic/theskeleton/role/UserRoleRestControllerTest.java b/src/test/java/org/codenergic/theskeleton/role/UserRoleRestControllerTest.java index 1cd1570..5eecd0f 100644 --- a/src/test/java/org/codenergic/theskeleton/role/UserRoleRestControllerTest.java +++ b/src/test/java/org/codenergic/theskeleton/role/UserRoleRestControllerTest.java @@ -50,7 +50,7 @@ @RunWith(SpringRunner.class) @EnableSpringDataWebSupport -@WebMvcTest(controllers = {UserRoleRestController.class}, secure = false) +@WebMvcTest(controllers = {UserRoleRestController.class}) @EnableRestDocs @InjectUserDetailsService public class UserRoleRestControllerTest { diff --git a/src/test/java/org/codenergic/theskeleton/user/UserRestControllerTest.java b/src/test/java/org/codenergic/theskeleton/user/UserRestControllerTest.java index 99df821..7e8be74 100644 --- a/src/test/java/org/codenergic/theskeleton/user/UserRestControllerTest.java +++ b/src/test/java/org/codenergic/theskeleton/user/UserRestControllerTest.java @@ -11,6 +11,7 @@ import org.apache.commons.io.IOUtils; import org.codenergic.theskeleton.client.OAuth2ClientEntity; import org.codenergic.theskeleton.core.test.EnableRestDocs; +import org.codenergic.theskeleton.core.test.EnableSecurityConfig; import org.codenergic.theskeleton.tokenstore.TokenStoreService; import org.junit.Test; import org.junit.runner.RunWith; @@ -36,6 +37,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.verify; @@ -49,8 +51,9 @@ @RunWith(SpringRunner.class) @EnableSpringDataWebSupport -@WebMvcTest(controllers = { UserRestController.class }, secure = false) +@WebMvcTest(controllers = { UserRestController.class }) @EnableRestDocs +@EnableSecurityConfig public class UserRestControllerTest { @Autowired private MockMvc mockMvc; @@ -69,7 +72,7 @@ public void testUpdateUserPicture() throws Exception { .setId("user123") .setUsername("user") .setEmail("user@server"); - when(userService.updateUserPicture(eq("user123"), any(), eq("image/png"))).thenReturn(user); + when(userService.updateUserPicture(eq("user123"), any(), eq("image/png"), anyLong())).thenReturn(user); InputStream image = ClassLoader.getSystemResourceAsStream("static/logo.png"); MockHttpServletRequestBuilder request = put("/api/users/user123/picture") .content(IOUtils.toByteArray(image)) @@ -81,7 +84,7 @@ public void testUpdateUserPicture() throws Exception { assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getContentAsByteArray()) .isEqualTo(objectMapper.writeValueAsBytes(userMapper.toUserData(user))); - verify(userService).updateUserPicture(eq("user123"), any(), eq("image/png")); + verify(userService).updateUserPicture(eq("user123"), any(), eq("image/png"), anyLong()); image.close(); } diff --git a/src/test/java/org/codenergic/theskeleton/user/UserServiceTest.java b/src/test/java/org/codenergic/theskeleton/user/UserServiceTest.java index 86ad898..bf0b967 100644 --- a/src/test/java/org/codenergic/theskeleton/user/UserServiceTest.java +++ b/src/test/java/org/codenergic/theskeleton/user/UserServiceTest.java @@ -10,6 +10,7 @@ import java.util.UUID; import org.codenergic.theskeleton.client.OAuth2ClientEntity; +import org.codenergic.theskeleton.core.data.S3ClientProperties; import org.codenergic.theskeleton.core.security.ImmutableUser; import org.codenergic.theskeleton.core.security.User; import org.codenergic.theskeleton.privilege.RolePrivilegeRepository; @@ -29,11 +30,11 @@ import org.springframework.security.oauth2.provider.approval.Approval; import io.minio.MinioClient; +import io.minio.ObjectWriteResponse; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -52,12 +53,13 @@ public class UserServiceTest { private SessionRegistry sessionRegistry; @Mock private UserAuthorityService userAuthorityService; + private S3ClientProperties s3ClientProperties = new S3ClientProperties(); private UserService userService; @Before public void init() { MockitoAnnotations.initMocks(this); - this.userService = new UserServiceImpl(minioClient, passwordEncoder, userRepository, userAuthorityService, clientApprovalRepository, sessionRegistry); + this.userService = new UserServiceImpl(minioClient, passwordEncoder, userRepository, userAuthorityService, clientApprovalRepository, sessionRegistry, s3ClientProperties); } @Test @@ -212,12 +214,12 @@ public void testUpdateUserPassword() { @Test public void testUpdateUserPicture() throws Exception { - final InputStream inputStream = ClassLoader.getSystemResourceAsStream("static/logo.png"); - when(userRepository.findByUsername("user")).thenReturn(Optional.of(new UserEntity())); - userService.updateUserPicture("user", inputStream, "image/png"); - verify(userRepository).findByUsername("user"); - verify(minioClient).putObject(anyString(), anyString(), any(InputStream.class), eq("image/png")); - verify(minioClient).getObjectUrl(anyString(), anyString()); - inputStream.close(); + try (InputStream inputStream = ClassLoader.getSystemResourceAsStream("static/logo.png")) { + when(minioClient.putObject(any())).thenReturn(new ObjectWriteResponse(null, "bucket", "region", "object", "etag", "version")); + when(userRepository.findByUsername("user")).thenReturn(Optional.of(new UserEntity())); + userService.updateUserPicture("user", inputStream, "image/png", 0); + verify(userRepository).findByUsername("user"); + verify(minioClient).putObject(any()); + } } } From 00ec42f1b8a857f746e8d33c78151d38a1b08789 Mon Sep 17 00:00:00 2001 From: Dian Aditya Date: Sat, 6 Feb 2021 11:08:34 +0700 Subject: [PATCH 5/5] Upgrade greenmail version --- pom.xml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index cd2ae43..1254623 100644 --- a/pom.xml +++ b/pom.xml @@ -26,6 +26,7 @@ 4.1.0 3.11 1.1.0 + 1.6.2 30.1-jre 2.8.8 0.8.6 @@ -37,7 +38,6 @@ 2.4.2 0.6.3 2.0.5.RELEASE - 2.5.0.RELEASE UTF-8 UTF-8 1.8 @@ -193,7 +193,7 @@ com.icegreen greenmail - 1.5.5 + ${greenmail.version} test @@ -201,7 +201,6 @@ org.apache.commons commons-lang3 - ${commons-lang3.version} commons-io