MyBatis 플러그인 수정

master
mjkhan21 11 months ago
parent e6357b5cd6
commit 5ed401050c

@ -156,6 +156,9 @@ public class ARIA extends AbstractComponent {
* @return * @return
*/ */
public String decrypt(String encrypted) { public String decrypt(String encrypted) {
if (isEmpty(encrypted))
return "";
byte[] bytes = Base64.getDecoder().decode(encrypted); byte[] bytes = Base64.getDecoder().decode(encrypted);
return new String(service().decrypt(bytes, key)); return new String(service().decrypt(bytes, key));
} }

@ -0,0 +1,133 @@
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.Map;
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 cokr.xit.foundation.data.ARIA;
@Intercepts({
@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 = new ARIA();
private List<String> decrypted = Collections.emptyList();
private List<Adaptor> adaptors = Collections.emptyList();
@Override
protected void configure() {
String str = properties.getProperty("enabled", "");
enabled = !"false".equals(str);
str = properties.getProperty("enc.key");
aria.setKey(str);
str = properties.getProperty("enc.algorithm");
if (!isEmpty(str))
aria.setAlgorithm(str);
str = properties.getProperty("dec.fields", "");
if (!isEmpty(str))
decrypted = List.of(str.split(","));
str = properties.getProperty("enc.adaptor", "");
if (isEmpty(str)) return;
adaptors = Stream.of(str.split(",")).map(name -> {
try {
Class<?> klass = Class.forName(name);
Adaptor adaptor = (Adaptor)klass.getConstructor().newInstance();
adaptor.setARIA(aria);
return adaptor;
} catch (Exception e) {
throw runtimeException(e);
}
}).toList();
}
@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 || decrypted.isEmpty()) return;
if (obj instanceof Map)
decrypt((Map<String, Object>)obj);
}
protected void decrypt(Map<String, Object> map) {
decrypted.forEach(k -> {
if (!map.containsKey(k)) return;
Object v = map.get(k);
map.put(k, aria.decrypt((String)v));
});
}
@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.setTarget(obj)) return;
adaptor.encrypt();
adaptor.clear();
}
public abstract static class Adaptor {
protected ARIA aria;
protected Object obj;
public Adaptor setARIA(ARIA aria) {
this.aria = aria;
return this;
}
public boolean setTarget(Object obj) {
this.obj = obj;
return true;
}
public abstract void encrypt();
public void clear() {
obj = null;
}
}
}

@ -71,11 +71,11 @@ public class MapperSupport extends MybatisPlugin {
now = ifEmpty(now, () -> dateFormat.format(new Date())); now = ifEmpty(now, () -> dateFormat.format(new Date()));
if (arg instanceof AbstractEntity) { if (arg instanceof AbstractEntity) {
setTimestamp(sqlType, (AbstractEntity)arg, now); setTimestamp(sqlType, (AbstractEntity)arg, now);
} else if (arg instanceof Map<?, ?>) { } else if (arg instanceof Map) {
Map<?, ?> map = (Map<?, ?>)arg; Map<?, ?> map = (Map<?, ?>)arg;
for (Object o: map.values()) for (Object o: map.values())
setEntityTimestamp(sqlType, o, now); setEntityTimestamp(sqlType, o, now);
} else if (arg instanceof Iterable<?>) { } else if (arg instanceof Iterable) {
Iterable<?> iterable = (Iterable<?>)arg; Iterable<?> iterable = (Iterable<?>)arg;
for (Object o: iterable) for (Object o: iterable)
setEntityTimestamp(sqlType, o, now); setEntityTimestamp(sqlType, o, now);

@ -5,6 +5,9 @@ import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.Map;
import java.util.Properties;
import java.util.function.Consumer;
import org.apache.ibatis.executor.Executor; import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.parameter.ParameterHandler; import org.apache.ibatis.executor.parameter.ParameterHandler;
@ -38,6 +41,16 @@ import cokr.xit.foundation.AbstractComponent;
@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class}) @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})
}) })
public class MybatisPlugin extends AbstractComponent implements Interceptor { public class MybatisPlugin extends AbstractComponent implements Interceptor {
protected Properties properties;
@Override
public void setProperties(Properties properties) {
this.properties = properties;
configure();
}
protected void configure() {}
@Override @Override
public Object intercept(Invocation invocation) throws Throwable { public Object intercept(Invocation invocation) throws Throwable {
Object target = invocation.getTarget(); Object target = invocation.getTarget();
@ -110,4 +123,21 @@ public class MybatisPlugin extends AbstractComponent implements Interceptor {
protected Object handle(ResultSetHandler resultSetHandler, Statement statement) throws SQLException { protected Object handle(ResultSetHandler resultSetHandler, Statement statement) throws SQLException {
return resultSetHandler.handleResultSets(statement); return resultSetHandler.handleResultSets(statement);
} }
protected void process(Object obj, Consumer<Object> processor) {
if (obj instanceof Map) {
Map<?, ?> map = (Map<?, ?>)obj;
map.values().forEach(processor);
} else if (obj instanceof Iterable) {
Iterable<?> objs = (Iterable<?>)obj;
for (Object o: objs)
processor.accept(o);
} else if (obj.getClass().isArray()) {
Object[] objs = (Object[])obj;
for (Object o: objs)
processor.accept(o);
} else {
processor.accept(obj);
}
}
} }
Loading…
Cancel
Save