diff --git a/src/main/java/com/bartek/esa/EsaMain.java b/src/main/java/com/bartek/esa/EsaMain.java index 781496d..c3a9461 100644 --- a/src/main/java/com/bartek/esa/EsaMain.java +++ b/src/main/java/com/bartek/esa/EsaMain.java @@ -2,11 +2,13 @@ package com.bartek.esa; import com.bartek.esa.cli.model.CliArgsOptions; import com.bartek.esa.cli.parser.CliArgsParser; +import com.bartek.esa.core.model.object.Issue; import com.bartek.esa.di.DaggerDependencyInjector; import com.bartek.esa.dispatcher.dispatcher.MethodDispatcher; import com.bartek.esa.dispatcher.model.DispatcherActions; import javax.inject.Inject; +import java.util.List; public class EsaMain { private final CliArgsParser cliArgsParser; @@ -20,13 +22,13 @@ public class EsaMain { private void run(String[] args) { DispatcherActions dispatcherActions = DispatcherActions.builder() - .sourceAnalysis(source -> {}) - .apkAudit(source -> {}) + .sourceAnalysis((source, plugins, excludes) -> null) + .apkAudit((source, plugins, excludes) -> null) .build(); CliArgsOptions options = cliArgsParser.parse(args); - methodDispatcher.dispatchMethod(options, dispatcherActions); + List issues = methodDispatcher.dispatchMethod(options, dispatcherActions); } public static void main(String[] args) { diff --git a/src/main/java/com/bartek/esa/core/analyser/Analyser.java b/src/main/java/com/bartek/esa/core/analyser/Analyser.java new file mode 100644 index 0000000..6a0fa99 --- /dev/null +++ b/src/main/java/com/bartek/esa/core/analyser/Analyser.java @@ -0,0 +1,83 @@ +package com.bartek.esa.core.analyser; + +import com.bartek.esa.core.archetype.Plugin; +import com.bartek.esa.core.executor.PluginExecutor; +import com.bartek.esa.core.model.object.Issue; +import com.bartek.esa.error.EsaException; +import com.bartek.esa.file.provider.FileProvider; + +import javax.inject.Inject; +import java.io.File; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class Analyser { + private final FileProvider fileProvider; + private final PluginExecutor pluginExecutor; + private final Set plugins; + + @Inject + public Analyser(FileProvider fileProvider, PluginExecutor pluginExecutor, Set plugins) { + this.fileProvider = fileProvider; + + this.pluginExecutor = pluginExecutor; + this.plugins = plugins; + } + + public List analyse(String source, Set pluginCodes, Set excludeCodes) { + File manifest = getManifest(source); + Set files = getFiles(source); + Set selectedPlugins = getPlugins(pluginCodes, excludeCodes); + + return pluginExecutor.executeForFiles(manifest, files, selectedPlugins); + } + + private File getManifest(String source) { + Set manifests = fileProvider.getGlobMatchedFiles(source, "**/AndroidManifest.xml"); + if (manifests.isEmpty()) { + throw new EsaException("No AndroidManifest.xml file found. Interrupting..."); + } + + if (manifests.size() > 1) { + throw new EsaException("Found multiple AndroidManifest.xml files. Interrupting..."); + } + + return (File) (manifests.toArray())[0]; + } + + private Set getFiles(String source) { + Set javaFiles = fileProvider.getGlobMatchedFiles(source, "**/*.java"); + Set androidManifest = fileProvider.getGlobMatchedFiles(source, "**/AndroidManifest.xml"); + Set layoutFiles = fileProvider.getGlobMatchedFiles(source, "**/res/layout*/**.xml"); + + return Stream.of(javaFiles, androidManifest, layoutFiles) + .flatMap(Set::stream) + .collect(Collectors.toSet()); + } + + private Set getPlugins(Set pluginCodes, Set excludeCodes) { + Set outputPlugins = plugins; + + if (!pluginCodes.isEmpty()) { + outputPlugins = plugins.stream() + .filter(plugin -> pluginCodes + .stream() + .anyMatch(pluginCode -> plugin.getClass().getCanonicalName().equals(pluginCode)) + ) + .collect(Collectors.toSet()); + } + + if(!excludeCodes.isEmpty()) { + outputPlugins = outputPlugins.stream() + .filter(plugin -> excludeCodes + .stream() + .noneMatch(pluginCode -> plugin.getClass().getCanonicalName().equals(pluginCode)) + ) + .collect(Collectors.toSet()); + } + + return outputPlugins; + } +} diff --git a/src/main/java/com/bartek/esa/core/di/CoreModule.java b/src/main/java/com/bartek/esa/core/di/CoreModule.java index 59d666d..2b54b7b 100644 --- a/src/main/java/com/bartek/esa/core/di/CoreModule.java +++ b/src/main/java/com/bartek/esa/core/di/CoreModule.java @@ -1,12 +1,17 @@ package com.bartek.esa.core.di; +import com.bartek.esa.core.analyser.Analyser; +import com.bartek.esa.core.archetype.Plugin; import com.bartek.esa.core.desc.provider.DescriptionProvider; import com.bartek.esa.core.executor.PluginExecutor; import com.bartek.esa.core.java.JavaSyntaxRegexProvider; import com.bartek.esa.core.xml.XmlHelper; +import com.bartek.esa.file.provider.FileProvider; import dagger.Module; import dagger.Provides; +import java.util.Set; + @Module public class CoreModule { @@ -29,4 +34,9 @@ public class CoreModule { public XmlHelper xmlHelper() { return new XmlHelper(); } + + @Provides + public Analyser analyser(FileProvider fileProvider, PluginExecutor pluginExecutor, Set plugins) { + return new Analyser(fileProvider, pluginExecutor, plugins); + } } diff --git a/src/main/java/com/bartek/esa/core/di/PluginModule.java b/src/main/java/com/bartek/esa/core/di/PluginModule.java new file mode 100644 index 0000000..c1474b2 --- /dev/null +++ b/src/main/java/com/bartek/esa/core/di/PluginModule.java @@ -0,0 +1,19 @@ +package com.bartek.esa.core.di; + +import com.bartek.esa.core.archetype.Plugin; +import dagger.Module; +import dagger.Provides; +import dagger.multibindings.ElementsIntoSet; + +import java.util.HashSet; +import java.util.Set; + +@Module +public class PluginModule { + + @Provides + @ElementsIntoSet + public Set plugins() { + return new HashSet<>(); + } +} diff --git a/src/main/java/com/bartek/esa/core/executor/PluginExecutor.java b/src/main/java/com/bartek/esa/core/executor/PluginExecutor.java index e114489..c3b585a 100644 --- a/src/main/java/com/bartek/esa/core/executor/PluginExecutor.java +++ b/src/main/java/com/bartek/esa/core/executor/PluginExecutor.java @@ -8,6 +8,7 @@ import org.w3c.dom.Document; import javax.inject.Inject; import java.io.File; import java.util.List; +import java.util.Set; import static java.util.stream.Collectors.toList; @@ -19,14 +20,14 @@ public class PluginExecutor { this.xmlHelper = xmlHelper; } - public List executeForFiles(File manifest, List files, List plugins) { + public List executeForFiles(File manifest, Set files, Set plugins) { return files.stream() .map(file -> executeForFile(manifest, file, plugins)) .flatMap(List::stream) .collect(toList()); } - private List executeForFile(File manifest, File file, List plugins) { + private List executeForFile(File manifest, File file, Set plugins) { Document xmlManifest = xmlHelper.parseXml(manifest); return plugins.stream() .filter(plugin -> plugin.supports(file)) diff --git a/src/main/java/com/bartek/esa/di/DependencyInjector.java b/src/main/java/com/bartek/esa/di/DependencyInjector.java index b05f447..9793337 100644 --- a/src/main/java/com/bartek/esa/di/DependencyInjector.java +++ b/src/main/java/com/bartek/esa/di/DependencyInjector.java @@ -3,6 +3,7 @@ package com.bartek.esa.di; import com.bartek.esa.EsaMain; import com.bartek.esa.cli.di.CliModule; import com.bartek.esa.core.di.CoreModule; +import com.bartek.esa.core.di.PluginModule; import com.bartek.esa.decompiler.di.DecompilerModule; import com.bartek.esa.dispatcher.di.DispatcherModule; import com.bartek.esa.file.di.FileModule; @@ -13,7 +14,8 @@ import dagger.Component; DispatcherModule.class, FileModule.class, DecompilerModule.class, - CoreModule.class + CoreModule.class, + PluginModule.class }) public interface DependencyInjector { EsaMain esa(); diff --git a/src/main/java/com/bartek/esa/dispatcher/dispatcher/MethodDispatcher.java b/src/main/java/com/bartek/esa/dispatcher/dispatcher/MethodDispatcher.java index 306795d..29711ad 100644 --- a/src/main/java/com/bartek/esa/dispatcher/dispatcher/MethodDispatcher.java +++ b/src/main/java/com/bartek/esa/dispatcher/dispatcher/MethodDispatcher.java @@ -1,9 +1,12 @@ package com.bartek.esa.dispatcher.dispatcher; import com.bartek.esa.cli.model.CliArgsOptions; +import com.bartek.esa.core.model.object.Issue; import com.bartek.esa.dispatcher.model.DispatcherActions; import javax.inject.Inject; +import java.util.Collections; +import java.util.List; public class MethodDispatcher { @@ -12,14 +15,22 @@ public class MethodDispatcher { } - public void dispatchMethod(CliArgsOptions options, DispatcherActions actions) { + public List dispatchMethod(CliArgsOptions options, DispatcherActions actions) { if(options.isSourceAnalysis()) { - actions.getSourceAnalysis().accept(options.getSourceAnalysisDirectory()); - return; + return actions.getSourceAnalysis().perform( + options.getSourceAnalysisDirectory(), + options.getPlugins(), + options.getExcludes() + ); } if(options.isApkAudit()) { - actions.getApkAudit().accept(options.getApkAuditFile()); + return actions.getApkAudit().perform(options.getApkAuditFile(), + options.getPlugins(), + options.getExcludes() + ); } + + return Collections.emptyList(); } } diff --git a/src/main/java/com/bartek/esa/dispatcher/model/Action.java b/src/main/java/com/bartek/esa/dispatcher/model/Action.java new file mode 100644 index 0000000..b7ba664 --- /dev/null +++ b/src/main/java/com/bartek/esa/dispatcher/model/Action.java @@ -0,0 +1,12 @@ +package com.bartek.esa.dispatcher.model; + +import com.bartek.esa.core.model.object.Issue; + +import java.util.List; +import java.util.Set; + +@FunctionalInterface +public interface Action { + + List perform(String source, Set plugins, Set excludes); +} diff --git a/src/main/java/com/bartek/esa/dispatcher/model/DispatcherActions.java b/src/main/java/com/bartek/esa/dispatcher/model/DispatcherActions.java index a3411c8..28f242f 100644 --- a/src/main/java/com/bartek/esa/dispatcher/model/DispatcherActions.java +++ b/src/main/java/com/bartek/esa/dispatcher/model/DispatcherActions.java @@ -3,11 +3,9 @@ package com.bartek.esa.dispatcher.model; import lombok.Builder; import lombok.Data; -import java.util.function.Consumer; - @Data @Builder public class DispatcherActions { - private Consumer sourceAnalysis; - private Consumer apkAudit; + private Action sourceAnalysis; + private Action apkAudit; }