From 18fa96d134217accac8b66c3f22453865d58bd95 Mon Sep 17 00:00:00 2001 From: mjkhan21 Date: Fri, 19 Jan 2024 13:24:41 +0900 Subject: [PATCH] =?UTF-8?q?EncryptionSupport=20=EC=A0=9C=EA=B1=B0,=20Condi?= =?UTF-8?q?tionSupport=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 6 - .../java/cokr/xit/foundation/data/ARIA.java | 203 ------------------ .../data/paging/EncryptionSupport.java | 172 --------------- .../foundation/data/paging/MybatisPlugin.java | 2 +- .../xit/foundation/util/ConditionSupport.java | 30 +++ 5 files changed, 31 insertions(+), 382 deletions(-) delete mode 100644 src/main/java/cokr/xit/foundation/data/ARIA.java delete mode 100644 src/main/java/cokr/xit/foundation/data/paging/EncryptionSupport.java create mode 100644 src/main/java/cokr/xit/foundation/util/ConditionSupport.java diff --git a/pom.xml b/pom.xml index 9c7f863..c0e9737 100644 --- a/pom.xml +++ b/pom.xml @@ -78,12 +78,6 @@ ${org.egovframe.rte.version} - - org.egovframe.rte - org.egovframe.rte.fdl.crypto - ${org.egovframe.rte.version} - - com.sun.xml.bind jaxb-core diff --git a/src/main/java/cokr/xit/foundation/data/ARIA.java b/src/main/java/cokr/xit/foundation/data/ARIA.java deleted file mode 100644 index 3f642bd..0000000 --- a/src/main/java/cokr/xit/foundation/data/ARIA.java +++ /dev/null @@ -1,203 +0,0 @@ -package cokr.xit.foundation.data; - -import java.util.Base64; -import java.util.List; -import java.util.function.BiConsumer; -import java.util.function.Function; - -import org.egovframe.rte.fdl.cryptography.EgovPasswordEncoder; -import org.egovframe.rte.fdl.cryptography.impl.EgovARIACryptoServiceImpl; - -import cokr.xit.foundation.AbstractComponent; - -/**ARIA 기반의 암/복호화 서비스를 제공하는 컴포넌트 - * @author mjkhan - */ -public class ARIA extends AbstractComponent { - private String - key, - algorithm; - private int blockSize; - - private EgovPasswordEncoder passwordEncoder; - private EgovARIACryptoServiceImpl aria; - - /**키를 반환한다. - * @return 키 - */ - public String getKey() { - if (!isEmpty(key)) - return key; - - if (properties != null) { - return key = properties.getString("aria.key"); - } else { - return key; - } - } - - /**키를 설정한다. - * @param key 키 - * @return 현재 ARIA - */ - public ARIA setKey(String key) { - this.key = key; - return this; - } - - /**알고리즘을 반환한다. 디폴트는 SHA-256. - * @return 알고리즘 - */ - public String getAlgorithm() { - if (!isEmpty(algorithm)) - return algorithm; - - if (properties != null) { - return algorithm = properties.getString("aria.algorithm"); - } else { - return algorithm; - } - } - - /**알고리즘을 설정한다. 디폴트는 SHA-256. - * @param algorithm 알고리즘 - * @return 현재 ARIA - */ - public ARIA setAlgorithm(String algorithm) { - this.algorithm = algorithm; - return this; - } - - /**블록사이즈를 반환한다. 디폴트는 1024. - * @return 블록사이즈 - */ - public int getBlockSize() { - return blockSize < 1 ? 1024 : blockSize; - } - - /**블록사이즈를 설정한다. 디폴트는 1024. - * @param blockSize 블록사이즈 - * @return 현재 ARIA - */ - public ARIA setBlockSize(int blockSize) { - this.blockSize = blockSize; - return this; - } - - /**주어진 문자열(평문)을 암호화하여 반환한다. - * @param plain 문자열(평문) - * @return 암호화한 문자열 - */ - public String encrypt(String plain) { - if (isEmpty(plain)) return ""; - - byte[] bytes = service().encrypt(plain.getBytes(), key); - return Base64.getEncoder().encodeToString(bytes); - } - - public void encrypt(Function getter, BiConsumer setter, Iterable objs) { - convert( - obj -> { - String str = getter.apply(obj); - return encrypt(str); - }, - setter, - objs - ); - } - - public void encrypt(Function getter, BiConsumer setter, T... objs) { - encrypt(getter, setter, List.of(objs)); - } - - public void encrypt(String fieldName, Iterable rows) { - encrypt( - row -> row.string(fieldName), - (row, str) -> row.set(fieldName, str), - rows - ); - } - - public void encrypt(String fieldName, DataObject... rows) { - encrypt(fieldName, List.of(rows)); - } - - private void convert(Function converter, BiConsumer setter, Iterable objs) { - if (isEmpty(objs)) return; - - objs.forEach(obj -> { - String str = converter.apply(obj); - setter.accept(obj, str); - }); - } - - private EgovPasswordEncoder passwordEncoder() { - if (passwordEncoder == null) { - passwordEncoder = new EgovPasswordEncoder(); - String hashed = passwordEncoder.encryptPassword(notEmpty(key, "key")); - passwordEncoder.setHashedPassword(hashed); - if (!isEmpty(algorithm)) - passwordEncoder.setAlgorithm(algorithm); - } - return passwordEncoder; - } - - private EgovARIACryptoServiceImpl service() { - if (aria == null) { - aria = new EgovARIACryptoServiceImpl(); - aria.setPasswordEncoder(passwordEncoder()); - aria.setBlockSize(getBlockSize()); - } - return aria; - } - - /**주어진 문자열(암호화)을 복호화하여 반환한다. - * @param encrypted 문자열(암호화) - * @return 복호화한 문자열 - */ - public String decrypt(String encrypted) { - if (isEmpty(encrypted)) - return ""; - - byte[] bytes = Base64.getDecoder().decode(encrypted); - return new String(service().decrypt(bytes, key)); - } - - public void decrypt(Function getter, BiConsumer setter, Iterable objs) { - convert( - obj -> { - String str = getter.apply(obj); - return decrypt(str); - }, - setter, - objs - ); - } - - public void decrypt(Function getter, BiConsumer setter, T... objs) { - decrypt(getter, setter, List.of(objs)); - } - - public void decrypt(String fieldName, Iterable rows) { - decrypt( - row -> row.string(fieldName), - (row, str) -> row.set(fieldName, str), - rows - ); - } - - public void decrypt(String fieldName, DataObject... rows) { - decrypt(fieldName, List.of(rows)); - } - - /**현재 설정상태를 비운다. - * @return 현재 ARIA - */ - public ARIA clear() { - key = algorithm = null; - blockSize = 0; - passwordEncoder = null; - aria = null; - return this; - } -} \ No newline at end of file diff --git a/src/main/java/cokr/xit/foundation/data/paging/EncryptionSupport.java b/src/main/java/cokr/xit/foundation/data/paging/EncryptionSupport.java deleted file mode 100644 index 4f76dd7..0000000 --- a/src/main/java/cokr/xit/foundation/data/paging/EncryptionSupport.java +++ /dev/null @@ -1,172 +0,0 @@ -package cokr.xit.foundation.data.paging; - -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Collections; -import java.util.List; -import java.util.function.Consumer; -import java.util.function.Supplier; -import java.util.stream.Stream; - -import org.apache.ibatis.executor.Executor; -import org.apache.ibatis.executor.resultset.ResultSetHandler; -import org.apache.ibatis.mapping.MappedStatement; -import org.apache.ibatis.plugin.Intercepts; -import org.apache.ibatis.plugin.Signature; -import org.apache.ibatis.session.ResultHandler; -import org.apache.ibatis.session.RowBounds; - -import cokr.xit.foundation.data.ARIA; - -@Intercepts({ - @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}), - @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class}), - - @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}), -}) -public class EncryptionSupport extends MybatisPlugin { - private boolean enabled; - private ARIA aria; - - private List adaptors = Collections.emptyList(); - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public void setEncryptor(ARIA encryptor) { - this.aria = encryptor; - } - - public void setAdaptors(Adaptor... adaptors) { - this.adaptors = List.of(adaptors); - this.adaptors.forEach(adaptor -> adaptor.setARIA(aria)); - } - - @Override - protected void configure() { - String str = properties.getProperty("enabled", ""); - setEnabled(!"false".equals(str)); - - if (aria == null) { - aria = new ARIA(); - aria.setKey(properties.getProperty("enc.key")); - str = properties.getProperty("enc.algorithm"); - if (!isEmpty(str)) - aria.setAlgorithm(str); - } - - str = properties.getProperty("enc.adaptor", ""); - if (isEmpty(str)) return; - - List adaptors = Stream.of(str.split(",")).map(name -> { - try { - Class klass = Class.forName(name); - return (Adaptor)klass.getConstructor().newInstance(); - } catch (Exception e) { - throw runtimeException(e); - } - }).toList(); - setAdaptors(adaptors.toArray(new Adaptor[adaptors.size()])); - } - - @Override - protected Object query(Executor executor, MappedStatement mappedStatement, Object obj, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException { - encrypt(obj); - return executor.query(mappedStatement, obj, rowBounds, resultHandler); - } - - @Override - protected Object handle(ResultSetHandler resultSetHandler, Statement statement) throws SQLException { - Object obj = super.handle(resultSetHandler, statement); - - if (obj instanceof List) { - List list = (List)obj; - list.forEach(this::decrypt); - } else { - decrypt(obj); - } - - return obj; - } - - private void decrypt(Object obj) { - if (!enabled || adaptors.isEmpty()) return; - - adaptors.forEach(adaptor -> { - if (!adaptor.supports(obj)) return; - - adaptor - .setTarget(obj) - .decrypt() - .clear(); - }); - } - - @Override - protected Object update(Executor executor, MappedStatement mappedStatement, Object obj) throws SQLException { - switch (mappedStatement.getSqlCommandType()) { - case INSERT: - case UPDATE: encrypt(obj); break; - default: break; - } - - return super.update(executor, mappedStatement, obj); - } - - private void encrypt(Object obj) { - if (!enabled || obj == null || adaptors.isEmpty()) return; - - process(obj, arg -> adaptors.forEach(adaptor -> encrypt(adaptor, arg))); - } - - private void encrypt(Adaptor adaptor, Object obj) { - if (!adaptor.supports(obj)) return; - - adaptor - .setTarget(obj) - .encrypt() - .clear(); - } - - public abstract static class Adaptor { - protected ARIA aria; - protected Object obj; - - public Adaptor setARIA(ARIA aria) { - this.aria = aria; - return this; - } - - public Adaptor setTarget(Object obj) { - this.obj = obj; - return this; - } - - public abstract boolean supports(Object obj); - - public abstract boolean isEncrypted(String str); - - public abstract Adaptor encrypt(); - - public abstract Adaptor decrypt(); - - protected void encrypt(Supplier getter, Consumer setter) { - String plain = getter.get(); - if (isEmpty(plain) || isEncrypted(plain)) return; - - setter.accept(aria.encrypt(plain)); - } - - protected void decrypt(Supplier getter, Consumer setter) { - String encrypted = getter.get(); - if (isEmpty(encrypted) || !isEncrypted(encrypted)) return; - - setter.accept(aria.decrypt(encrypted)); - } - - public void clear() { - obj = null; - } - } -} \ No newline at end of file diff --git a/src/main/java/cokr/xit/foundation/data/paging/MybatisPlugin.java b/src/main/java/cokr/xit/foundation/data/paging/MybatisPlugin.java index 0f3db06..0a0ce3e 100644 --- a/src/main/java/cokr/xit/foundation/data/paging/MybatisPlugin.java +++ b/src/main/java/cokr/xit/foundation/data/paging/MybatisPlugin.java @@ -58,7 +58,7 @@ public class MybatisPlugin extends AbstractComponent implements Interceptor { Object[] args = invocation.getArgs(); String methodName = method.toString(); - System.out.println(methodName); + log().debug(methodName); if (methodName.contains("Executor.query")) return query((Executor)target, (MappedStatement)args[0], args[1], (RowBounds)args[2], (ResultHandler)args[3]); diff --git a/src/main/java/cokr/xit/foundation/util/ConditionSupport.java b/src/main/java/cokr/xit/foundation/util/ConditionSupport.java new file mode 100644 index 0000000..a045df6 --- /dev/null +++ b/src/main/java/cokr/xit/foundation/util/ConditionSupport.java @@ -0,0 +1,30 @@ +package cokr.xit.foundation.util; + +import java.io.InputStream; + +import org.springframework.context.annotation.Condition; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.type.AnnotatedTypeMetadata; + +public class ConditionSupport { + public static class InBoot implements Condition { + private Boolean inBoot; + + @Override + public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { + if (inBoot != null) + return inBoot; + + try { + InputStream input = new ClassPathResource("application.yml").getInputStream(); + if (input == null) + input = new ClassPathResource("application.properties").getInputStream(); + + return inBoot = input != null; + } catch (Exception e) { + return inBoot = false; + } + } + } +} \ No newline at end of file