Skip to content

Instantly share code, notes, and snippets.

@wreulicke
Last active February 22, 2018 15:32
Show Gist options
  • Save wreulicke/37b551dd0bec7455d4e8eb1669dc8b8c to your computer and use it in GitHub Desktop.
Save wreulicke/37b551dd0bec7455d4e8eb1669dc8b8c to your computer and use it in GitHub Desktop.
見せられないよ!!
apply plugin: 'java'
repositories {
jcenter()
}
dependencies {
compile "org.slf4j:slf4j-api:1.7.25"
testCompile "ch.qos.logback:logback-classic:1.1.11"
compileOnly "org.projectlombok:lombok:1.16.20"
testCompileOnly "org.projectlombok:lombok:1.16.20"
testCompile 'junit:junit:4.12'
testCompile 'org.assertj:assertj-core:3.8.0'
// 今回使う、メインのライブラリ: http://spoon.gforge.inria.fr/
compile 'fr.inria.gforge.spoon:spoon-core:5.8.0'
}
package com.github.wreulicke.ast.spoon;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import com.google.common.collect.ImmutableSet;
import spoon.Launcher;
import spoon.SpoonAPI;
import spoon.reflect.code.CtFieldAccess;
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.visitor.filter.TypeFilter;
@Slf4j
public class NoSensitiveToStringTest {
// 見せたくないフィールド
Set<String> secrets = ImmutableSet.of("secret");
/**
* サンプル例: 見せたくないフィールドをtoStringに吐きたくないよ!!
* @throws IOException
*/
@Test
public void test() throws IOException {
SpoonAPI spoon = new Launcher();
// 解析対象
spoon.addInputResource("src/main/java/");
spoon.buildModel();
for (CtClass<?> clazz : spoon.getModel()
// クラスを取り出して
.getElements(new TypeFilter<>(CtClass.class))) {
// toStringだけ取り出す。
List<CtMethod<?>> toStrings = clazz.getElements(new TypeFilter<CtMethod<?>>(CtMethod.class) {
@Override public boolean matches(CtMethod<?> element) {
log.info(element.getSignature());
return super.matches(element) && Objects.equals(element.getSignature(), "java.lang.String toString()");
}
});
// メソッドの中のフィールドアクセスを取り出して
List<CtFieldAccess> sensitiveList = toStrings.stream().flatMap(method ->
method.getElements(new TypeFilter<>(CtFieldAccess.class)).stream()
)
// 見せたくないフィールド名を探す
.filter(access ->
secrets.contains(access.getVariable().getSimpleName())
).collect(Collectors.toList());
// サンプルなので、とりあえずログに吐いてる。
if (sensitiveList.isEmpty() == false)
sensitiveList.stream()
.map(ctFieldAccess -> String.format(Locale.ENGLISH, "Exposed `%s` from toString. %s", ctFieldAccess.getVariable().getSimpleName(), ctFieldAccess.getPosition().toString()))
.forEach(log::info);
log.info("{}", sensitiveList);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment