From b2c0a1574cb06565f262ca378ef007fa06f4ebb1 Mon Sep 17 00:00:00 2001 From: Lim Jonguk Date: Mon, 10 Jan 2022 04:07:52 +0900 Subject: [PATCH] =?UTF-8?q?test=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 25 ++-- .../{ => database}/DataSourceConfig.java | 136 +++++++++++++----- .../config/support/SpringDocApiConfig.java | 2 +- .../com/xit/core/constant/XitConstants.java | 91 +++++++----- .../oauth2/api/service/impl/AuthService.java | 18 +-- .../core/oauth2/oauth/AuthInterceptor.java | 4 +- .../core/oauth2/oauth/JwtTokenProvider.java | 16 +-- .../OAuth2AuthenticationSuccessHandler.java | 4 +- ...izationRequestBasedOnCookieRepository.java | 4 +- .../com/xit/core/oauth2/utils/HeaderUtil.java | 6 +- .../xit/core/oauth2/utils/SecurityUtil.java | 6 +- .../com/xit/core/support/jpa/Paginator.java | 2 +- .../paging/OffsetLimitInterceptor.java | 2 +- .../mybatis/paging/domain/Paginator.java | 2 +- .../java/com/xit/core/util/AwsFileUtil.java | 2 +- .../resources/config/application-test.yml | 31 +++- src/main/resources/config/application.yml | 2 + .../core}/OAuth2LocalControllerTest.java | 51 +++---- 18 files changed, 249 insertions(+), 155 deletions(-) rename src/main/java/com/xit/core/config/{ => database}/DataSourceConfig.java (60%) rename src/test/java/com/xit/core/{oauth2/api/controller => controller/core}/OAuth2LocalControllerTest.java (79%) diff --git a/build.gradle b/build.gradle index a76e217..90111fa 100644 --- a/build.gradle +++ b/build.gradle @@ -116,23 +116,23 @@ dependencies { //compileOnly 'com.querydsl:querydsl-apt' // JPA mapstruct : lombok 과 함께 사용시 반드시 순서 지겨야 함다 - lombok이 먼저 선언된 경우 -// implementation 'org.projectlombok:lombok-mapstruct-binding:0.2.0' -// implementation 'org.projectlombok:lombok' -// implementation 'org.mapstruct:mapstruct:1.4.2.Final' -// annotationProcessor "org.projectlombok:lombok-mapstruct-binding:0.2.0" -// annotationProcessor 'org.projectlombok:lombok' -// annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final' + implementation 'org.projectlombok:lombok-mapstruct-binding:0.2.0' + implementation 'org.projectlombok:lombok' + implementation 'org.mapstruct:mapstruct:1.4.2.Final' + annotationProcessor "org.projectlombok:lombok-mapstruct-binding:0.2.0" + annotationProcessor 'org.projectlombok:lombok' + annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final' // JPA mapstruct : lombok 과 함께 사용시 반드시 순서 지겨야 함다 - ㅡmapstruct이 먼저 선언된 경우 // target class 에 @Builder 가 있어도 무시하고 생성자 + setter 를 사용하므로 정상적으로 Mapper 클래스를 Generation 하기 위해서 // @NoArgsConstructor, @Setter 가 필요 // but, 최근 Setter 사용을 지양하는 추세라 mapstruct를 먼저 오도록 해서 @Builder 방식으로 Generation - implementation 'org.mapstruct:mapstruct:1.4.2.Final' - implementation 'org.projectlombok:lombok-mapstruct-binding:0.2.0' - implementation 'org.projectlombok:lombok' - annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final' - annotationProcessor "org.projectlombok:lombok-mapstruct-binding:0.2.0" - annotationProcessor 'org.projectlombok:lombok' +// implementation 'org.mapstruct:mapstruct:1.4.2.Final' +// implementation 'org.projectlombok:lombok-mapstruct-binding:0.2.0' +// implementation 'org.projectlombok:lombok' +// annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final' +// annotationProcessor "org.projectlombok:lombok-mapstruct-binding:0.2.0" +// annotationProcessor 'org.projectlombok:lombok' //-----------------------------------------------------------------------------------// //-----------------------------------------------------------------------------------// @@ -212,6 +212,7 @@ dependencies { implementation 'com.fasterxml.jackson.module:jackson-module-afterburner:2.13.1' implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.1' implementation 'com.fasterxml.jackson.datatype:jackson-datatype-joda:2.13.1' + // response xml implementation 'javax.xml.bind:jaxb-api:2.3.1' //implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.12.5' //-----------------------------------------------------------------------------------// diff --git a/src/main/java/com/xit/core/config/DataSourceConfig.java b/src/main/java/com/xit/core/config/database/DataSourceConfig.java similarity index 60% rename from src/main/java/com/xit/core/config/DataSourceConfig.java rename to src/main/java/com/xit/core/config/database/DataSourceConfig.java index 65332fc..ecf9c28 100644 --- a/src/main/java/com/xit/core/config/DataSourceConfig.java +++ b/src/main/java/com/xit/core/config/database/DataSourceConfig.java @@ -1,4 +1,4 @@ -package com.xit.core.config; +package com.xit.core.config.database; import com.xit.core.support.CamelCaseLinkedMap; import com.xit.core.support.CamelCaseMap; @@ -15,6 +15,9 @@ import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties; +import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings; import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; @@ -23,12 +26,16 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; +import org.springframework.context.annotation.Profile; import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.data.transaction.ChainedTransactionManager; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.vendor.Database; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; @@ -38,6 +45,7 @@ import java.sql.Time; import java.sql.Timestamp; import java.util.Arrays; import java.util.HashSet; +import java.util.Map; @Slf4j @Configuration @@ -67,10 +75,9 @@ public class DataSourceConfig { this.applicationContext = applicationContext; } - @Primary - @Bean(name = "apiDataSource") + @Bean @ConfigurationProperties("spring.datasource.hikari") - public DataSource apiDataSource() { + public DataSource dataSource() { return DataSourceBuilder.create() .type(HikariDataSource.class) .build(); @@ -79,54 +86,64 @@ public class DataSourceConfig { //////////////////////////////////////////////////////////////////////////////////////////// // JPA /////////////////////////////////////////////////////////////////////////////////////////// - @Primary - @Bean(name = "jpaProperties") + @Bean @ConfigurationProperties(prefix = "spring.jpa") public JpaProperties jpaProperties() { return new JpaProperties(); } - @Primary - @Bean(name = "entityManagerFactory") - public LocalContainerEntityManagerFactoryBean entityManagerFactory( - EntityManagerFactoryBuilder builder, - @Qualifier("apiDataSource") DataSource apiDataSource, - @Qualifier("jpaProperties") JpaProperties jpaProperties - ) { - return builder - .dataSource(apiDataSource) - .properties(jpaProperties.getProperties()) - .packages(ENTITY_PACKAGES) - .persistenceUnit("default") - .build(); + @Profile("!test") + @Bean + public LocalContainerEntityManagerFactoryBean entityManagerFactory(@Value("${spring.jpa.properties.hibernate.hbm2ddl.auto}") String hbm2ddlAuto) { +// return builder +// .dataSource(dataSource) +// .properties(jpaProperties.getProperties()) +// .packages(ENTITY_PACKAGES) +// .persistenceUnit("default") +// .build(); + + HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); + vendorAdapter.setDatabasePlatform(jpaProperties().getDatabasePlatform()); + vendorAdapter.setDatabase(jpaProperties().getDatabase()); + + HibernateProperties hibernateProperties = new HibernateProperties(); + hibernateProperties.setDdlAuto(hbm2ddlAuto); + Map propMap = hibernateProperties.determineHibernateProperties( + jpaProperties().getProperties() + , new HibernateSettings()); + + LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean(); + emf.setDataSource(dataSource()); + emf.setPackagesToScan(ENTITY_PACKAGES); + emf.setPersistenceUnitName("default"); + emf.setJpaVendorAdapter(vendorAdapter); + emf.setJpaPropertyMap(propMap); //jpaProperties().getProperties()); + return emf; } @Primary - @Bean(name = "jpaTransactionManager") - public PlatformTransactionManager jpaTransactionManager( - @Qualifier(value = "entityManagerFactory") LocalContainerEntityManagerFactoryBean entityManagerFactory) { + @Bean + public PlatformTransactionManager jpaTransactionManager(LocalContainerEntityManagerFactoryBean entityManagerFactory) { JpaTransactionManager transactionManager = new JpaTransactionManager(); transactionManager.setEntityManagerFactory(entityManagerFactory.getObject()); transactionManager.setNestedTransactionAllowed(true); return transactionManager; } - @Primary @Bean - public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){ + public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { return new PersistenceExceptionTranslationPostProcessor(); } ///////////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////////////////// // Mybatis /////////////////////////////////////////////////////////////////////////////////////////// - @Bean(name="sqlSessionFactory") - public SqlSessionFactory sqlSessionFactory(@Qualifier("apiDataSource") DataSource apiDataSource) throws Exception{ + @Bean + public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception { final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); - sessionFactory.setDataSource(apiDataSource); + sessionFactory.setDataSource(dataSource); //sessionFactory.setConfiguration(mybatisConfiguration()); sessionFactory.setConfigLocation(applicationContext.getResource("classpath:/config/mybatis-config.xml")); //sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATION)); @@ -134,14 +151,14 @@ public class DataSourceConfig { return sessionFactory.getObject(); } - @Bean(name="sqlSessionTemplate") + @Bean public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory hikariSqlSessionFactory) { return new SqlSessionTemplate(hikariSqlSessionFactory); } - @Bean(name = "mybatisTransactionManager") + @Bean public PlatformTransactionManager mybatisTransactionManager() { - DataSourceTransactionManager dstm = new DataSourceTransactionManager(apiDataSource()); + DataSourceTransactionManager dstm = new DataSourceTransactionManager(dataSource()); dstm.setGlobalRollbackOnParticipationFailure(false); return dstm; } @@ -160,7 +177,7 @@ public class DataSourceConfig { conf.setMapUnderscoreToCamelCase(true); conf.setLocalCacheScope(LocalCacheScope.SESSION); // SESSION / STATEMENT conf.setJdbcTypeForNull(JdbcType.OTHER); // NULL / VARCHAR / OTHER 파라메터에 null 값이 있는경우 처리 - conf.setLazyLoadTriggerMethods(new HashSet(Arrays.asList("equals","clone","hashCode","toString"))); + conf.setLazyLoadTriggerMethods(new HashSet(Arrays.asList("equals", "clone", "hashCode", "toString"))); conf.setCallSettersOnNulls(true); // 조회시 null값 필드 set conf.setAggressiveLazyLoading(true); conf.setReturnInstanceForEmptyRow(true); @@ -186,6 +203,61 @@ public class DataSourceConfig { } ////////////////////////////////////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////////////////////////////////////// + // ChainedTransactionManager : trsnsaction binding + /////////////////////////////////////////////////////////////////////////////////////////// +// /** +// * jap & mybatis Transaction binding +// * @param entityManagerFactory LocalContainerEntityManagerFactoryBean +// * @return PlatformTransactionManager +// * @throws Exception Exception +// */ +// @Bean +// public PlatformTransactionManager transactionManager(LocalContainerEntityManagerFactoryBean entityManagerFactory) throws Exception { +// +// // JPA transactionManager +// JpaTransactionManager jpaTransactionManager = new JpaTransactionManager(); +// jpaTransactionManager.setEntityManagerFactory(entityManagerFactory.getObject()); +// jpaTransactionManager.setNestedTransactionAllowed(true); +// +// // MYBATIS transactionManager +// DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(); +// dataSourceTransactionManager.setDataSource(dataSource()); +// dataSourceTransactionManager.setGlobalRollbackOnParticipationFailure(false); +// +// // creates chained transaction manager +// return new ChainedTransactionManager(jpaTransactionManager, dataSourceTransactionManager); +// } + + ///////////////////////////////////////////////////////////////////////////////////// + + + //////////////////////////////////////////////////////////////////////////////////////////// + // Test + /////////////////////////////////////////////////////////////////////////////////////////// + @Profile("test") + @Bean + public LocalContainerEntityManagerFactoryBean testManagerFactory(@Value("${spring.jpa.properties.hibernate.hbm2ddl.auto}") String hbm2ddlAuto) { + + HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); + vendorAdapter.setDatabasePlatform(jpaProperties().getDatabasePlatform()); + vendorAdapter.setDatabase(jpaProperties().getDatabase()); + + HibernateProperties hibernateProperties = new HibernateProperties(); + hibernateProperties.setDdlAuto(hbm2ddlAuto); + Map propMap = hibernateProperties.determineHibernateProperties( + jpaProperties().getProperties() + , new HibernateSettings()); + + LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean(); + emf.setDataSource(dataSource()); + emf.setPackagesToScan(ENTITY_PACKAGES); + emf.setPersistenceUnitName("test"); + emf.setJpaVendorAdapter(vendorAdapter); + emf.setJpaPropertyMap(propMap); //jpaProperties().getProperties()); + return emf; + } } diff --git a/src/main/java/com/xit/core/config/support/SpringDocApiConfig.java b/src/main/java/com/xit/core/config/support/SpringDocApiConfig.java index 1fd60aa..7bcf629 100644 --- a/src/main/java/com/xit/core/config/support/SpringDocApiConfig.java +++ b/src/main/java/com/xit/core/config/support/SpringDocApiConfig.java @@ -49,7 +49,7 @@ public class SpringDocApiConfig { // Token SecurityScheme securityScheme = new SecurityScheme() .type(SecurityScheme.Type.HTTP).scheme("bearer").bearerFormat("JWT") - .in(SecurityScheme.In.HEADER).name(XitConstants.JwtToken.HEADER_NAME.getValue()); + .in(SecurityScheme.In.HEADER).name(XitConstants.JwtToken.HEADER_NAME.getCode()); SecurityRequirement schemaRequirement = new SecurityRequirement().addList("bearerAuth"); return new OpenAPI() diff --git a/src/main/java/com/xit/core/constant/XitConstants.java b/src/main/java/com/xit/core/constant/XitConstants.java index d783b77..444ee72 100644 --- a/src/main/java/com/xit/core/constant/XitConstants.java +++ b/src/main/java/com/xit/core/constant/XitConstants.java @@ -15,7 +15,7 @@ public class XitConstants { public static final int CONNECT_TIMEOUT = 30 * 1000; // 30초 public static final int READ_TIMEOUT = 60 * 1000 * 3; // 3분 public static final Charset CHARSET = StandardCharsets.UTF_8; - public static final String DEFAULT_VIEW = ViewName.JSON_VIEW.getValue(); + public static final String DEFAULT_VIEW = ViewName.JSON_VIEW.getCode(); /** * CustomCommonsRequestLoggingFilter에서 로깅을 제외할 url 패턴 정의 @@ -26,13 +26,17 @@ public class XitConstants { LOCAL("local"), DEV("dev"), STG("stg"), - PROD("prod"); - private final String value; - public String getValue() { - return this.value; + PROD("prod"), + TEST("test"); + + private final String code; + + ActiveProfile(String code) { + this.code = code; } - private ActiveProfile(String value) { - this.value = value; + + public String getCode() { + return this.code; } } @@ -44,12 +48,15 @@ public class XitConstants { SECURITY("security"), // SessionCreationPolicy.STATELESS인 경우는 SecurityContext 사용불가 SESSION("session"), // TOKEN도 사용 가능은 하지만... HEADER("header"); // TOKEN - private final String value; - public String getValue() { - return this.value; + + private final String code; + + AuthSaveType(String code) { + this.code = code; } - private AuthSaveType(String value) { - this.value = value; + + public String getCode() { + return this.code; } } @@ -61,13 +68,15 @@ public class XitConstants { REFRESH_TOKEN_NAME("refreshToken"), AUTHORITIES_KEY("role") ; - ; - private final String value; - public String getValue() { - return this.value; + + private final String code; + + JwtToken(String code) { + this.code = code; } - private JwtToken(String value) { - this.value = value; + + public String getCode() { + return this.code; } } @@ -86,12 +95,13 @@ public class XitConstants { public enum ViewName{ JSON_VIEW("mappingJackson2JsonView") ; - private String value; - private ViewName(String value) { - this.value = value; + private String code; + + ViewName(String code) { + this.code = code; } - public String getValue() { - return this.value; + public String getCode() { + return this.code; } } @@ -116,13 +126,14 @@ public class XitConstants { AuthentSessionAuthority("AUTH_SS_AUTHORITY"), ; - private String value; - private Session( String value ) { - this.value = value; + private String code; + + Session( String code ) { + this.code = code; } - public String getValue() { - return this.value; + public String getCode() { + return this.code; } } @@ -138,19 +149,20 @@ public class XitConstants { EucKr( "EUC-KR" ), Iso8859("8859_1"); - private String value; - private CharsetType( String value ) { - this.value = value; + private String code; + + CharsetType( String code) { + this.code = code; } - public String getValue() { - return this.value; + public String getCode() { + return this.code; } public Charset getCharset() { if ( this == Default ) return Charset.defaultCharset(); - return Charset.forName( this.value ); + return Charset.forName( this.code); } public byte[] getBytes( String str ) { @@ -181,12 +193,13 @@ public class XitConstants { NEXT_SYMBOLIC(" ▷ "), LAST_SYMBOLIC(" ▶ "); - private String value; - private PageNavigator(String value) { - this.value = value; + private String code; + + PageNavigator(String code) { + this.code = code; } - public String getValue() { - return this.value; + public String getCode() { + return this.code; } } } diff --git a/src/main/java/com/xit/core/oauth2/api/service/impl/AuthService.java b/src/main/java/com/xit/core/oauth2/api/service/impl/AuthService.java index fd79d5a..2454eb1 100644 --- a/src/main/java/com/xit/core/oauth2/api/service/impl/AuthService.java +++ b/src/main/java/com/xit/core/oauth2/api/service/impl/AuthService.java @@ -87,11 +87,11 @@ public class AuthService implements IAuthService { authentication = authenticationManager.authenticate(authenticationToken); // Authentication 저장 - if(Objects.equals(authSaveType, XitConstants.AuthSaveType.SECURITY.getValue())){ + if(Objects.equals(authSaveType, XitConstants.AuthSaveType.SECURITY.getCode())){ // TODO :: SessionCreationPolicy.STATELESS 인 경우 사용 불가 SecurityContextHolder.getContext().setAuthentication(authentication); - }else if(Objects.equals(authSaveType, XitConstants.AuthSaveType.SESSION.getValue())){ + }else if(Objects.equals(authSaveType, XitConstants.AuthSaveType.SESSION.getCode())){ session.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext()); } @@ -134,7 +134,7 @@ public class AuthService implements IAuthService { }else{ tokenDto = TokenDto.builder() - .grantType(XitConstants.JwtToken.GRANT_TYPE.getValue()) + .grantType(XitConstants.JwtToken.GRANT_TYPE.getCode()) .accessToken(jwtTokenProvider.generateJwtAccessToken(authentication, infoMap)) .refreshToken(null) .build(); @@ -162,8 +162,8 @@ public class AuthService implements IAuthService { // COOKIE 타입의 요청인 경우 COOKIE set if(Objects.equals(XitConstants.JwtTokenParamType.COOKIE.name(), tokenParamType)) { - CookieUtil.deleteCookie(request, response, XitConstants.JwtToken.REFRESH_TOKEN_NAME.getValue()); - CookieUtil.addCookie(response, XitConstants.JwtToken.REFRESH_TOKEN_NAME.getValue(), tokenDto.getRefreshToken(), appProperties.getAuth().getRefreshTokenExpiry() * EXPIRE_CONVERT_SECOND_FROM_DAY); + CookieUtil.deleteCookie(request, response, XitConstants.JwtToken.REFRESH_TOKEN_NAME.getCode()); + CookieUtil.addCookie(response, XitConstants.JwtToken.REFRESH_TOKEN_NAME.getCode(), tokenDto.getRefreshToken(), appProperties.getAuth().getRefreshTokenExpiry() * EXPIRE_CONVERT_SECOND_FROM_DAY); } // 5. 토큰 발급 @@ -227,7 +227,7 @@ public class AuthService implements IAuthService { //--------------------------------------------------------- // Get refresh token -------------------------------------- if(Objects.equals(XitConstants.JwtTokenParamType.COOKIE.name(), tokenParamType)) - sRefreshToken = CookieUtil.getCookie(request, XitConstants.JwtToken.REFRESH_TOKEN_NAME.getValue()) + sRefreshToken = CookieUtil.getCookie(request, XitConstants.JwtToken.REFRESH_TOKEN_NAME.getCode()) .map(Cookie::getValue) .orElse((null)); else if(Objects.equals(XitConstants.JwtTokenParamType.HEADER.name(), tokenParamType) @@ -268,13 +268,13 @@ public class AuthService implements IAuthService { //refreshTokenRepository.saveAndFlush(newRefreshToken); if(Objects.equals(XitConstants.JwtTokenParamType.COOKIE.name(), tokenParamType)) { - CookieUtil.deleteCookie(request, response, XitConstants.JwtToken.REFRESH_TOKEN_NAME.getValue()); - CookieUtil.addCookie(response, XitConstants.JwtToken.REFRESH_TOKEN_NAME.getValue(), newRefreshToken.getValue(), appProperties.getAuth().getRefreshTokenExpiry() * EXPIRE_CONVERT_SECOND_FROM_DAY); + CookieUtil.deleteCookie(request, response, XitConstants.JwtToken.REFRESH_TOKEN_NAME.getCode()); + CookieUtil.addCookie(response, XitConstants.JwtToken.REFRESH_TOKEN_NAME.getCode(), newRefreshToken.getValue(), appProperties.getAuth().getRefreshTokenExpiry() * EXPIRE_CONVERT_SECOND_FROM_DAY); } }else{ tokenDto = TokenDto.builder() - .grantType(XitConstants.JwtToken.GRANT_TYPE.getValue()) + .grantType(XitConstants.JwtToken.GRANT_TYPE.getCode()) .accessToken(jwtTokenProvider.generateJwtAccessToken(authentication, infoMap)) .refreshToken(null) .build(); diff --git a/src/main/java/com/xit/core/oauth2/oauth/AuthInterceptor.java b/src/main/java/com/xit/core/oauth2/oauth/AuthInterceptor.java index 3b538ee..25016dd 100644 --- a/src/main/java/com/xit/core/oauth2/oauth/AuthInterceptor.java +++ b/src/main/java/com/xit/core/oauth2/oauth/AuthInterceptor.java @@ -48,12 +48,12 @@ public class AuthInterceptor implements AsyncHandlerInterceptor {//AsyncHandlerI if (Objects.equals(SecurityPolicy.TOKEN, policy)) { log.debug("TOKEN 인증 start ==>> "); - String tokenString = request.getHeader(XitConstants.JwtToken.HEADER_NAME.getValue()); + String tokenString = request.getHeader(XitConstants.JwtToken.HEADER_NAME.getCode()); if(Checks.isNotEmpty(tokenString)){ try{ - tokenString = tokenString.substring(XitConstants.JwtToken.GRANT_TYPE.getValue().length()+1); + tokenString = tokenString.substring(XitConstants.JwtToken.GRANT_TYPE.getCode().length()+1); if(SpringUtils.getJwtTokenProvider().validateTokenExcludeExpired(tokenString, false, true)){ log.debug("<<==== 토큰인증성공"); return true; diff --git a/src/main/java/com/xit/core/oauth2/oauth/JwtTokenProvider.java b/src/main/java/com/xit/core/oauth2/oauth/JwtTokenProvider.java index 7068ee6..7bb3ccc 100644 --- a/src/main/java/com/xit/core/oauth2/oauth/JwtTokenProvider.java +++ b/src/main/java/com/xit/core/oauth2/oauth/JwtTokenProvider.java @@ -149,13 +149,13 @@ public class JwtTokenProvider { throw new TokenAuthException(ErrorCode.INVALID_TOKEN); } - if (claims.get(XitConstants.JwtToken.AUTHORITIES_KEY.getValue()) == null) { + if (claims.get(XitConstants.JwtToken.AUTHORITIES_KEY.getCode()) == null) { throw new TokenAuthException(ErrorCode.INVALID_ROLE_TOKEN); } // 클레임에서 권한 정보 가져오기 Collection authorities = - Arrays.stream(claims.get(XitConstants.JwtToken.AUTHORITIES_KEY.getValue()).toString().split(",")) + Arrays.stream(claims.get(XitConstants.JwtToken.AUTHORITIES_KEY.getCode()).toString().split(",")) .map(SimpleGrantedAuthority::new) .collect(Collectors.toList()); @@ -239,7 +239,7 @@ public class JwtTokenProvider { String refreshToken = getJwtRefreshToken(authentication.getName()); return TokenDto.builder() - .grantType(XitConstants.JwtToken.GRANT_TYPE.getValue()) + .grantType(XitConstants.JwtToken.GRANT_TYPE.getCode()) .accessToken(accessToken) .refreshToken(refreshToken) .build(); @@ -253,10 +253,10 @@ public class JwtTokenProvider { Collection authorities = null; - if (claims.get(XitConstants.JwtToken.AUTHORITIES_KEY.getValue()) != null) { + if (claims.get(XitConstants.JwtToken.AUTHORITIES_KEY.getCode()) != null) { // 클레임에서 권한 정보 가져오기 authorities = - Arrays.stream(claims.get(XitConstants.JwtToken.AUTHORITIES_KEY.getValue()).toString().split(",")) + Arrays.stream(claims.get(XitConstants.JwtToken.AUTHORITIES_KEY.getCode()).toString().split(",")) .map(SimpleGrantedAuthority::new) .collect(Collectors.toList()); } @@ -267,7 +267,7 @@ public class JwtTokenProvider { map.put("userId", claims.getSubject()); map.put("userName", claims.get("userName")); map.put("userEmail", claims.get("userEmail")); - map.put(XitConstants.JwtToken.AUTHORITIES_KEY.getValue(), authorities); + map.put(XitConstants.JwtToken.AUTHORITIES_KEY.getCode(), authorities); map.put("Issuer", claims.getIssuer()); map.put("IssuedAt", DateUtil.getFormatedDT(claims.getIssuedAt(), "yyyy-MM-dd HH:mm:ss")); } else { @@ -304,7 +304,7 @@ public class JwtTokenProvider { .setIssuer(auth.getIssure()) .setAudience(auth.getAudience()) .setSubject(userId) // payload "sub": "name" - ID - .claim(XitConstants.JwtToken.AUTHORITIES_KEY.getValue(), authorities) // payload "auth": "ROLE_USER" + .claim(XitConstants.JwtToken.AUTHORITIES_KEY.getCode(), authorities) // payload "auth": "ROLE_USER" .claim("userName", info.get("userName")) .claim("userEmail", info.get("userEmail")) .setIssuedAt(new Date()) @@ -317,7 +317,7 @@ public class JwtTokenProvider { .setIssuer(auth.getIssure()) .setAudience(auth.getAudience()) .setSubject(userId) // payload "sub": "name" - ID - .claim(XitConstants.JwtToken.AUTHORITIES_KEY.getValue(), authorities) // payload "auth": "ROLE_USER" + .claim(XitConstants.JwtToken.AUTHORITIES_KEY.getCode(), authorities) // payload "auth": "ROLE_USER" .setIssuedAt(new Date()) .signWith(key, Objects.equals("HS512", auth.getAlg())? SignatureAlgorithm.HS512 : SignatureAlgorithm.HS256) // header "alg": "HS512" .setExpiration(accessTokenExpiresIn) // payload "exp": 1516239022 (예시) diff --git a/src/main/java/com/xit/core/oauth2/oauth/handler/OAuth2AuthenticationSuccessHandler.java b/src/main/java/com/xit/core/oauth2/oauth/handler/OAuth2AuthenticationSuccessHandler.java index 26bb46a..8a11a1a 100644 --- a/src/main/java/com/xit/core/oauth2/oauth/handler/OAuth2AuthenticationSuccessHandler.java +++ b/src/main/java/com/xit/core/oauth2/oauth/handler/OAuth2AuthenticationSuccessHandler.java @@ -94,8 +94,8 @@ public class OAuth2AuthenticationSuccessHandler extends SimpleUrlAuthenticationS //userRefreshToken = new UserRefreshToken(userInfo.getId(), refreshToken); //refreshTokenRepository.saveAndFlush(refreshToken); } - CookieUtil.deleteCookie(request, response, XitConstants.JwtToken.REFRESH_TOKEN_NAME.getValue()); - CookieUtil.addCookie(response, XitConstants.JwtToken.REFRESH_TOKEN_NAME.getValue(), refreshToken, appProperties.getAuth().getRefreshTokenExpiry()); + CookieUtil.deleteCookie(request, response, XitConstants.JwtToken.REFRESH_TOKEN_NAME.getCode()); + CookieUtil.addCookie(response, XitConstants.JwtToken.REFRESH_TOKEN_NAME.getCode(), refreshToken, appProperties.getAuth().getRefreshTokenExpiry()); return UriComponentsBuilder.fromUriString(targetUrl) .queryParam("token", accessToken) diff --git a/src/main/java/com/xit/core/oauth2/oauth/repository/OAuth2AuthorizationRequestBasedOnCookieRepository.java b/src/main/java/com/xit/core/oauth2/oauth/repository/OAuth2AuthorizationRequestBasedOnCookieRepository.java index b77b902..a407253 100644 --- a/src/main/java/com/xit/core/oauth2/oauth/repository/OAuth2AuthorizationRequestBasedOnCookieRepository.java +++ b/src/main/java/com/xit/core/oauth2/oauth/repository/OAuth2AuthorizationRequestBasedOnCookieRepository.java @@ -27,7 +27,7 @@ public class OAuth2AuthorizationRequestBasedOnCookieRepository implements Author if (authorizationRequest == null) { CookieUtil.deleteCookie(request, response, OAUTH2_AUTHORIZATION_REQUEST_COOKIE_NAME); CookieUtil.deleteCookie(request, response, REDIRECT_URI_PARAM_COOKIE_NAME); - CookieUtil.deleteCookie(request, response, XitConstants.JwtToken.REFRESH_TOKEN_NAME.getValue()); + CookieUtil.deleteCookie(request, response, XitConstants.JwtToken.REFRESH_TOKEN_NAME.getCode()); return; } @@ -51,6 +51,6 @@ public class OAuth2AuthorizationRequestBasedOnCookieRepository implements Author public void removeAuthorizationRequestCookies(HttpServletRequest request, HttpServletResponse response) { CookieUtil.deleteCookie(request, response, OAUTH2_AUTHORIZATION_REQUEST_COOKIE_NAME); CookieUtil.deleteCookie(request, response, REDIRECT_URI_PARAM_COOKIE_NAME); - CookieUtil.deleteCookie(request, response, XitConstants.JwtToken.REFRESH_TOKEN_NAME.getValue()); + CookieUtil.deleteCookie(request, response, XitConstants.JwtToken.REFRESH_TOKEN_NAME.getCode()); } } diff --git a/src/main/java/com/xit/core/oauth2/utils/HeaderUtil.java b/src/main/java/com/xit/core/oauth2/utils/HeaderUtil.java index c5817e1..75bb3bf 100644 --- a/src/main/java/com/xit/core/oauth2/utils/HeaderUtil.java +++ b/src/main/java/com/xit/core/oauth2/utils/HeaderUtil.java @@ -21,14 +21,14 @@ public class HeaderUtil { } public static String getAccessToken(HttpServletRequest request) { - String headerValue = request.getHeader(XitConstants.JwtToken.HEADER_NAME.getValue()); + String headerValue = request.getHeader(XitConstants.JwtToken.HEADER_NAME.getCode()); if (headerValue == null) { return null; } - if (headerValue.startsWith(XitConstants.JwtToken.GRANT_TYPE.getValue())) { - return headerValue.substring(XitConstants.JwtToken.GRANT_TYPE.getValue().length()); + if (headerValue.startsWith(XitConstants.JwtToken.GRANT_TYPE.getCode())) { + return headerValue.substring(XitConstants.JwtToken.GRANT_TYPE.getCode().length()); } return null; diff --git a/src/main/java/com/xit/core/oauth2/utils/SecurityUtil.java b/src/main/java/com/xit/core/oauth2/utils/SecurityUtil.java index 67251c6..5163ea9 100644 --- a/src/main/java/com/xit/core/oauth2/utils/SecurityUtil.java +++ b/src/main/java/com/xit/core/oauth2/utils/SecurityUtil.java @@ -38,7 +38,7 @@ public class SecurityUtil { public static String getCurrentUserId(@NotNull final String authType) { // TODO :: SessionCreationPolicy.STATELESS 인 경우 사용 불가 - if(Objects.equals(authType, AuthSaveType.SECURITY.getValue())) { + if(Objects.equals(authType, AuthSaveType.SECURITY.getCode())) { final Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (authentication == null || authentication.getName() == null) { throw new UserAuthException(ErrorCode.NOT_EXISTS_SECURITY_AUTH); @@ -46,7 +46,7 @@ public class SecurityUtil { return authentication.getName(); // TODO :: Session에 저장한 경우 - Token도 가능은 하지만... - }else if(Objects.equals(authType, AuthSaveType.SESSION.getValue())) { + }else if(Objects.equals(authType, AuthSaveType.SESSION.getCode())) { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest(); HttpSession session = request.getSession(); Object o = session.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY); @@ -61,7 +61,7 @@ public class SecurityUtil { }else { throw new UserAuthException(ErrorCode.NOT_EXISTS_SECURITY_AUTH); } - }else if(Objects.equals(authType, AuthSaveType.HEADER.getValue())) { + }else if(Objects.equals(authType, AuthSaveType.HEADER.getCode())) { return HeaderUtil.getUserId(); }else{ diff --git a/src/main/java/com/xit/core/support/jpa/Paginator.java b/src/main/java/com/xit/core/support/jpa/Paginator.java index 626436e..a84a5cf 100644 --- a/src/main/java/com/xit/core/support/jpa/Paginator.java +++ b/src/main/java/com/xit/core/support/jpa/Paginator.java @@ -21,7 +21,7 @@ public class Paginator implements Serializable { } public void setSessionPagination(Paginator paginator){ - RequestContextHolder.currentRequestAttributes().setAttribute(XitConstants.Session.PAGE_INFO.getValue(), paginator, RequestAttributes.SCOPE_REQUEST); + RequestContextHolder.currentRequestAttributes().setAttribute(XitConstants.Session.PAGE_INFO.getCode(), paginator, RequestAttributes.SCOPE_REQUEST); } public int getPage() { diff --git a/src/main/java/com/xit/core/support/mybatis/paging/OffsetLimitInterceptor.java b/src/main/java/com/xit/core/support/mybatis/paging/OffsetLimitInterceptor.java index 21c0088..3b39a18 100644 --- a/src/main/java/com/xit/core/support/mybatis/paging/OffsetLimitInterceptor.java +++ b/src/main/java/com/xit/core/support/mybatis/paging/OffsetLimitInterceptor.java @@ -102,7 +102,7 @@ public class OffsetLimitInterceptor implements Interceptor { // log.debug("###################################################################################"); // log.debug("OffsetLimitInterceptor Page information ThreadLocal save::{} - {}", FEnum.Session.PAGE_INFO.getValue(), countFutrue.get()); // log.debug("###################################################################################"); - RequestContextHolder.currentRequestAttributes().setAttribute(XitConstants.Session.PAGE_INFO.getValue(), countFutrue.get(), RequestAttributes.SCOPE_REQUEST); + RequestContextHolder.currentRequestAttributes().setAttribute(XitConstants.Session.PAGE_INFO.getCode(), countFutrue.get(), RequestAttributes.SCOPE_REQUEST); // ContextThreadLocalHolder.setPageListThreadLocal(pageList); // return pageList; return new PageList(listFuture.get(), countFutrue.get()); } diff --git a/src/main/java/com/xit/core/support/mybatis/paging/domain/Paginator.java b/src/main/java/com/xit/core/support/mybatis/paging/domain/Paginator.java index f02b928..6d8ae85 100644 --- a/src/main/java/com/xit/core/support/mybatis/paging/domain/Paginator.java +++ b/src/main/java/com/xit/core/support/mybatis/paging/domain/Paginator.java @@ -21,7 +21,7 @@ public class Paginator implements Serializable { } public void setSessionPagination(Paginator paginator){ - RequestContextHolder.currentRequestAttributes().setAttribute(XitConstants.Session.PAGE_INFO.getValue(), paginator, RequestAttributes.SCOPE_REQUEST); + RequestContextHolder.currentRequestAttributes().setAttribute(XitConstants.Session.PAGE_INFO.getCode(), paginator, RequestAttributes.SCOPE_REQUEST); } public int getPage() { diff --git a/src/main/java/com/xit/core/util/AwsFileUtil.java b/src/main/java/com/xit/core/util/AwsFileUtil.java index 727c0de..84b22d9 100644 --- a/src/main/java/com/xit/core/util/AwsFileUtil.java +++ b/src/main/java/com/xit/core/util/AwsFileUtil.java @@ -75,7 +75,7 @@ public class AwsFileUtil { result.put("fileName", file.getOriginalFilename()); result.put("key", key); - if (Objects.equals(XitConstants.ActiveProfile.PROD.getValue(), env.getActiveProfiles()[0])) { + if (Objects.equals(XitConstants.ActiveProfile.PROD.getCode(), env.getActiveProfiles()[0])) { result.put("url", "https://image.newbalancemynb.com/" + key); } else { result.put("url", amazonS3.getUrl(bucketName, key)); diff --git a/src/main/resources/config/application-test.yml b/src/main/resources/config/application-test.yml index acc6669..5561217 100644 --- a/src/main/resources/config/application-test.yml +++ b/src/main/resources/config/application-test.yml @@ -12,10 +12,10 @@ spring: datasource: driver-class-name: org.h2.Driver - url: jdbc:h2:mem:xitdb;MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE + jdbc-url: jdbc:h2:mem:xitdb;MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE username: sa password: '' - hikari: + hikari-test: driver-class-name: ${spring.datasource.driver-class-name} jdbc-url: ${spring.datasource.url} username: ${spring.datasource.username} @@ -27,10 +27,35 @@ spring: properties: hibernate: format_sql: true - use_sql_comments: false + #use_sql_comments: false hbm2ddl: auto: create-drop + +# properties: +# order_inserts: true +# order_updates: true +# default_batch_fetch_size: ${chunkSize:100} +# current_session_context_class: org.springframework.orm.hibernate5.SpringSessionContext +# implicit_naming_strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy +# physical_naming_strategy: com.xit.core.config.support.LowercaseSnakePhysicalNamingStrategy +# hibernate: +# format_sql: true +# use_sql_comments: false +# hbm2ddl: +# auto: create-drop +# hbm2ddl: +# import_files_sql_extractor: org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor +# jdbc: +# batch_size: 20 +# lob: +# # postgres 사용시 createLob() 미구현 경고 삭제 +# non_contextual_creation: true +# # Jdbc 환경구성을 하는 과정에서 Default Metadata를 사용할 지 여부 +# temp: +# use_jdbc_metadata_defaults: false + + # thymeleaf: # cache: false diff --git a/src/main/resources/config/application.yml b/src/main/resources/config/application.yml index 2c1e0eb..d44172f 100644 --- a/src/main/resources/config/application.yml +++ b/src/main/resources/config/application.yml @@ -87,6 +87,7 @@ spring: jpa: # 템플릿 view 화면의 렌더링이 끝날 때 까지 Lazy fetch 가 가능하도록 해주는 속성 open-in-view: false + generate-ddl: false show-sql: true properties: order_inserts: true @@ -97,6 +98,7 @@ spring: physical_naming_strategy: com.xit.core.config.support.LowercaseSnakePhysicalNamingStrategy hibernate: hbm2ddl: + auto: none import_files_sql_extractor: org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor jdbc: batch_size: 20 diff --git a/src/test/java/com/xit/core/oauth2/api/controller/OAuth2LocalControllerTest.java b/src/test/java/com/xit/core/controller/core/OAuth2LocalControllerTest.java similarity index 79% rename from src/test/java/com/xit/core/oauth2/api/controller/OAuth2LocalControllerTest.java rename to src/test/java/com/xit/core/controller/core/OAuth2LocalControllerTest.java index 8eb8a40..2c0f8cb 100644 --- a/src/test/java/com/xit/core/oauth2/api/controller/OAuth2LocalControllerTest.java +++ b/src/test/java/com/xit/core/controller/core/OAuth2LocalControllerTest.java @@ -1,4 +1,4 @@ -package com.xit.core.oauth2.api.controller; +package com.xit.core.controller.core; import com.xit.biz.cmm.dto.CmmUserDto; import com.xit.biz.cmm.dto.struct.CmmUserMapstruct; @@ -7,6 +7,7 @@ import com.xit.biz.cmm.entity.CmmUser; import com.xit.biz.cmm.repository.ICmmRoleRepository; import com.xit.biz.cmm.repository.ICmmUserRepository; import com.xit.core.api.IRestResponse; +import com.xit.core.oauth2.api.controller.OAuth2LocalController; import com.xit.core.oauth2.api.dto.LoginRequestDto; import com.xit.core.oauth2.api.dto.TokenDto; import com.xit.core.oauth2.api.service.IAuthService; @@ -27,6 +28,7 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.context.annotation.ComponentScan; @@ -56,13 +58,16 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. //@RunWith(SpringRunner.class) //@RunWith(MockitoJUnitRunner.class) -//@ExtendWith(SpringExtension.class) -//@DataJpaTest -@SpringBootTest -@AutoConfigureMockMvc -@Transactional +@ExtendWith(SpringExtension.class) +@WebMvcTest(controllers = OAuth2LocalController.class) +//@SpringBootTest +//@AutoConfigureMockMvc +@ActiveProfiles(value = {"test"}) class OAuth2LocalControllerTest { + @Autowired + MockMvc mocMvc; + CmmUser user = CmmUser.builder() .providerType(ProviderType.LOCAL) .userId("minuk926") @@ -71,13 +76,12 @@ class OAuth2LocalControllerTest { .build(); - @Autowired - MockMvc mvc; + //@InjectMocks //private CmmUserMapstruct mapstruct = CmmUserMapstructImpl.INSTANCE; - @Autowired - ICmmUserRepository userRepository; + //@Autowired + //ICmmUserRepository userRepository; //@Autowired //ICmmRoleRepository roleRepository; @@ -92,7 +96,7 @@ class OAuth2LocalControllerTest { .password("Minuk926!@") .build(); user.setCmmUserId(UUID.randomUUID().toString().replaceAll("-", "")); - CmmUser cmmUser = userRepository.save(user); + //CmmUser cmmUser = userRepository.save(user); // userRepository.save(user); } @@ -105,34 +109,11 @@ class OAuth2LocalControllerTest { @Test void login() throws Exception { -// CmmUserMapstruct mapper = Mappers.getMapper(CmmUserMapstruct.class); -// -// // we have some built other ArchUnit-checks that make sure we can rely on this filter -// final long mapperCount = new ClassFileImporter().importPackages("com.demo.service.mapper") -// .stream() -// .filter(javaClass -> javaClass.getSimpleName().endsWith("Mapper")) -// .count(); -// -// final List mappers = List.of(ACCOUNT_MAPPER, PERSON_MAPPER, INVOICE_MAPPER); -// -// assertThat(mappers) -// .withFailMessage("Scanned number of mappers doesn't match the provided amount") -// .hasSize(Long.valueOf(mapperCount).intValue()); -// -// for (Object mapper : mappers) { -// test(mapper, easyRandom); -// } - - //CmmUserDto cmmUser = cmmUserMapstruct.toDto(user); -// - //user.setCmmUserId(UUID.randomUUID().toString().replaceAll("-", "")); - //CmmUser cmmUser = userRepository.save(user); - MultiValueMap params = new LinkedMultiValueMap<>(); params.add("providerType", ProviderType.LOCAL.name()); params.add("userId", "minuk926"); params.add("password", "Minuk926!@"); - mvc.perform(post("/api/vi/auth/login").params(params)) + mocMvc.perform(post("/api/vi/auth/login").params(params)) .andDo(print()) .andExpect(status().isOk()) .andExpect(jsonPath("$.success").value(true))