Skip to content

Commit

Permalink
feat: forbidden http access to distrust hosts (#441)
Browse files Browse the repository at this point in the history
  • Loading branch information
tangcent authored Apr 20, 2021
1 parent 94b4925 commit 43495e5
Show file tree
Hide file tree
Showing 73 changed files with 1,975 additions and 912 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import com.google.inject.Inject
import com.google.inject.Singleton
import com.google.inject.name.Named
import com.itangcent.common.utils.TimeSpanUtils
import com.itangcent.idea.plugin.settings.SettingBinder
import com.itangcent.idea.plugin.settings.helper.HttpSettingsHelper
import com.itangcent.idea.sqlite.SqliteDataResourceHelper
import com.itangcent.intellij.config.ConfigReader
import com.itangcent.intellij.config.resource.DefaultResourceResolver
import com.itangcent.intellij.config.resource.URLResource
import com.itangcent.intellij.context.ActionContext
import com.itangcent.intellij.file.LocalFileRepository
import com.itangcent.intellij.logger.Logger
import java.io.ByteArrayInputStream
import java.io.InputStream
import java.net.URL
Expand All @@ -30,6 +31,12 @@ open class CachedResourceResolver : DefaultResourceResolver() {
@Inject
private lateinit var configReader: ConfigReader

@Inject
private lateinit var httpSettingsHelper: HttpSettingsHelper

@Inject
protected val logger: Logger? = null

private val beanDAO: SqliteDataResourceHelper.ExpiredBeanDAO by lazy {
val context = ActionContext.getContext()
val sqliteDataResourceHelper = context!!.instance(SqliteDataResourceHelper::class)
Expand All @@ -49,6 +56,10 @@ open class CachedResourceResolver : DefaultResourceResolver() {
var valueBytes = beanDAO.get(key)
if (valueBytes == null) {
LOG.debug("read:$url")
if (!httpSettingsHelper.checkTrustUrl(url.toString(), false)) {
logger?.warn("[access forbidden] read:$url")
return byteArrayOf()
}
valueBytes = super.inputStream?.use { it.readBytes() }
valueBytes?.let {
beanDAO.set(key, it, System.currentTimeMillis() +
Expand All @@ -72,9 +83,9 @@ open class CachedResourceResolver : DefaultResourceResolver() {
get() = loadCache()?.let { String(it, Charsets.UTF_8) }

override fun onConnection(connection: URLConnection) {
ActionContext.getContext()?.instance(SettingBinder::class)
?.tryRead()?.httpTimeOut?.let {
connection.connectTimeout = it * 1000
ActionContext.getContext()?.instance(HttpSettingsHelper::class)
?.let {
connection.connectTimeout = it.httpTimeOut(TimeUnit.MILLISECONDS)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import com.itangcent.idea.plugin.api.export.postman.PostmanConfigReader
import com.itangcent.idea.plugin.api.export.postman.PostmanRequestBuilderListener
import com.itangcent.idea.plugin.api.export.spring.SpringRequestClassExporter
import com.itangcent.idea.plugin.config.RecommendConfigReader
import com.itangcent.idea.swing.ActiveWindowProvider
import com.itangcent.idea.swing.SimpleActiveWindowProvider
import com.itangcent.intellij.config.ConfigReader
import com.itangcent.intellij.context.ActionContext
import com.itangcent.intellij.extend.guice.singleton
Expand All @@ -38,6 +40,8 @@ class ApiDashBoardAction : ApiExportAction("ApiDashBoard") {

builder.bind(RequestBuilderListener::class) { it.with(ComponentRequestBuilderListener::class).singleton() }
builder.bindInstance("AVAILABLE_REQUEST_BUILDER_LISTENER", arrayOf<Any>(DefaultRequestBuilderListener::class, PostmanRequestBuilderListener::class))

builder.bind(ActiveWindowProvider::class) { it.with(SimpleActiveWindowProvider::class) }
}

override fun actionPerformed(actionContext: ActionContext, project: Project?, anActionEvent: AnActionEvent) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import com.itangcent.idea.plugin.api.export.core.*
import com.itangcent.idea.plugin.api.export.generic.GenericMethodDocClassExporter
import com.itangcent.idea.plugin.api.export.yapi.*
import com.itangcent.idea.plugin.config.RecommendConfigReader
import com.itangcent.idea.swing.ActiveWindowProvider
import com.itangcent.idea.swing.SimpleActiveWindowProvider
import com.itangcent.intellij.config.ConfigReader
import com.itangcent.intellij.context.ActionContext
import com.itangcent.intellij.extend.guice.singleton
Expand Down Expand Up @@ -41,6 +43,7 @@ class YapiDashBoardAction : ApiExportAction("YapiDashBoard") {
builder.bind(MethodDocBuilderListener::class) { it.with(ComponentMethodDocBuilderListener::class).singleton() }
builder.bindInstance("AVAILABLE_METHOD_DOC_BUILDER_LISTENER", arrayOf<Any>(DefaultMethodDocBuilderListener::class, YapiMethodDocBuilderListener::class))

builder.bind(ActiveWindowProvider::class) { it.with(SimpleActiveWindowProvider::class) }
}

override fun actionPerformed(actionContext: ActionContext, project: Project?, anActionEvent: AnActionEvent) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.itangcent.idea.plugin.api.export.core.*
import com.itangcent.idea.plugin.api.export.generic.GenericMethodDocClassExporter
import com.itangcent.idea.plugin.api.export.yapi.*
import com.itangcent.idea.plugin.config.RecommendConfigReader
import com.itangcent.idea.plugin.settings.helper.YapiTokenChecker
import com.itangcent.intellij.config.ConfigReader
import com.itangcent.intellij.context.ActionContext
import com.itangcent.intellij.extend.guice.singleton
Expand Down Expand Up @@ -43,6 +44,8 @@ class YapiExportAction : ApiExportAction("Export Yapi") {
builder.bindInstance("file.save.last.location.key", "com.itangcent.yapi.export.path")

builder.bind(PsiClassHelper::class) { it.with(YapiPsiClassHelper::class).singleton() }

builder.bind(YapiTokenChecker::class) { it.with(YapiTokenCheckerSupport::class).singleton() }
}

override fun actionPerformed(actionContext: ActionContext, project: Project?, anActionEvent: AnActionEvent) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.itangcent.common.kit.KVUtils
import com.itangcent.common.logger.traceError
import com.itangcent.common.utils.*
import com.itangcent.idea.plugin.settings.SettingBinder
import com.itangcent.idea.plugin.settings.helper.IntelligentSettingsHelper
import com.itangcent.intellij.config.rule.RuleComputer
import com.itangcent.intellij.context.ActionContext
import com.itangcent.intellij.jvm.DuckTypeHelper
Expand All @@ -21,10 +22,6 @@ import com.siyeh.ig.psiutils.ClassUtils
import java.lang.reflect.Method
import java.lang.reflect.Modifier
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap
import kotlin.collections.HashSet
import kotlin.collections.LinkedHashMap

/**
*1.Try infer the return type of method
Expand Down Expand Up @@ -56,6 +53,9 @@ class DefaultMethodInferHelper : MethodInferHelper {
@Inject
protected val settingBinder: SettingBinder? = null

@Inject
protected lateinit var intelligentSettingsHelper: IntelligentSettingsHelper

private val staticMethodCache: HashMap<Pair<PsiMethod, Array<Any?>?>, Any?> = HashMap()

private val methodStack: Stack<Infer> = Stack()
Expand All @@ -64,17 +64,8 @@ class DefaultMethodInferHelper : MethodInferHelper {

private var simpleJsonOption: Int = jsonOption and JsonOption.READ_GETTER.inv()

private var maxDeep: Int? = null

private var maxObjectDeep: Int = 4

private fun inferMaxDeep(): Int {
if (this.maxDeep == null) {
this.maxDeep = settingBinder!!.read().inferMaxDeep
}
return maxDeep!!
}

private val emptyCallMethodCache: HashMap<PsiMethod, Any?> = HashMap()

override fun inferReturn(psiMethod: PsiMethod, option: Int): Any? {
Expand All @@ -95,7 +86,7 @@ class DefaultMethodInferHelper : MethodInferHelper {
option: Int = DEFAULT_OPTION
): Any? {
actionContext!!.checkStatus()
if (methodStack.size < inferMaxDeep()) {
if (methodStack.size < intelligentSettingsHelper.inferMaxDeep()) {
try {
var inferRet: Any?
inferRet = callSimpleMethod(context, psiMethod, caller, args)
Expand Down Expand Up @@ -564,7 +555,7 @@ class DefaultMethodInferHelper : MethodInferHelper {
return when {
!needCompute(obj) -> obj
obj is Variable -> valueOf(obj.getValue())
obj is Delay -> valueOf(obj.unwrapped { })
obj is Delay -> valueOf(obj.unwrapped { })
obj is MutableMap<*, *> -> {
val copy = KV.create<Any?, Any?>()
obj.entries.forEach { copy[valueOf(it.key)] = valueOf(it.value) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ import com.itangcent.idea.plugin.api.ClassApiExporterHelper
import com.itangcent.idea.plugin.api.MethodInferHelper
import com.itangcent.idea.plugin.api.export.MethodFilter
import com.itangcent.idea.plugin.api.export.spring.SpringClassName
import com.itangcent.idea.plugin.settings.SettingBinder
import com.itangcent.idea.plugin.settings.group.JsonSetting
import com.itangcent.idea.plugin.settings.helper.IntelligentSettingsHelper
import com.itangcent.idea.psi.PsiMethodResource
import com.itangcent.intellij.config.rule.RuleComputer
import com.itangcent.intellij.config.rule.computer
Expand Down Expand Up @@ -71,10 +70,7 @@ abstract class AbstractRequestClassExporter : ClassExporter, Worker {
protected lateinit var requestBuilderListener: RequestBuilderListener

@Inject
protected val settingBinder: SettingBinder? = null

@Inject
protected val jsonSetting: JsonSetting? = null
protected lateinit var intelligentSettingsHelper: IntelligentSettingsHelper

@Inject
protected val duckTypeHelper: DuckTypeHelper? = null
Expand Down Expand Up @@ -519,7 +515,7 @@ abstract class AbstractRequestClassExporter : ClassExporter, Worker {
?: false, paramDesc
)
} else if (typeObject != null && typeObject is Map<*, *>) {
if (request.hasBodyOrForm() && formExpanded() && typeObject.isComplex()
if (request.hasBodyOrForm() && this.intelligentSettingsHelper.formExpanded() && typeObject.isComplex()
&& requestBuilderListener.addHeaderIfMissed(parameterExportContext,
request, "Content-Type", "multipart/form-data")) {
typeObject.flatValid(object : FieldConsumer {
Expand Down Expand Up @@ -601,7 +597,7 @@ abstract class AbstractRequestClassExporter : ClassExporter, Worker {
?: false, paramDesc
)
} else if (typeObject != null && typeObject is Map<*, *>) {
if (formExpanded() && typeObject.isComplex()
if (this.intelligentSettingsHelper.formExpanded() && typeObject.isComplex()
&& requestBuilderListener.addHeaderIfMissed(parameterExportContext,
request, "Content-Type", "multipart/form-data")) {
typeObject.flatValid(object : FieldConsumer {
Expand Down Expand Up @@ -673,15 +669,15 @@ abstract class AbstractRequestClassExporter : ClassExporter, Worker {

return when {
fromRule -> psiClassHelper!!.getTypeObject(duckType, method.psi(),
jsonSetting!!.jsonOptionForOutput(JsonOption.READ_COMMENT))
needInfer() && (!duckTypeHelper!!.isQualified(duckType) ||
this.intelligentSettingsHelper!!.jsonOptionForOutput(JsonOption.READ_COMMENT))
this.intelligentSettingsHelper.inferEnable() && (!duckTypeHelper!!.isQualified(duckType) ||
jvmClassHelper!!.isInterface(duckType)) -> {
logger!!.info("try infer return type of method[" + PsiClassUtils.fullNameOfMethod(method.psi()) + "]")
methodReturnInferHelper!!.inferReturn(method.psi())
// actionContext!!.callWithTimeout(20000) { methodReturnInferHelper.inferReturn(method) }
}
else -> psiClassHelper!!.getTypeObject(duckType, method.psi(),
jsonSetting!!.jsonOptionForOutput(JsonOption.READ_COMMENT))
this.intelligentSettingsHelper!!.jsonOptionForOutput(JsonOption.READ_COMMENT))
}
}

Expand All @@ -700,14 +696,6 @@ abstract class AbstractRequestClassExporter : ClassExporter, Worker {
return obj
}

private fun needInfer(): Boolean {
return settingBinder!!.read().inferEnable
}

protected fun formExpanded(): Boolean {
return settingBinder!!.read().formExpanded
}

//region extent of ParameterExportContext
fun ParameterExportContext.setName(name: String) {
this.setExt("param_name", name)
Expand Down Expand Up @@ -737,7 +725,7 @@ abstract class AbstractRequestClassExporter : ClassExporter, Worker {
return this.cache("raw") {
val paramType = this.parameter.getType() ?: return@cache null
val typeObject = psiClassHelper!!.getTypeObject(paramType, parameter.psi(),
jsonSetting!!.jsonOptionForInput(JsonOption.READ_COMMENT))
this@AbstractRequestClassExporter.intelligentSettingsHelper!!.jsonOptionForInput(JsonOption.READ_COMMENT))
this.setExt("raw", typeObject)
return@cache typeObject
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ import com.itangcent.idea.plugin.api.MethodInferHelper
import com.itangcent.idea.plugin.api.export.MethodFilter
import com.itangcent.idea.plugin.api.export.core.*
import com.itangcent.idea.plugin.api.export.core.LinkResolver
import com.itangcent.idea.plugin.settings.SettingBinder
import com.itangcent.idea.plugin.settings.group.JsonSetting
import com.itangcent.idea.plugin.settings.helper.IntelligentSettingsHelper
import com.itangcent.idea.plugin.settings.helper.SupportSettingsHelper
import com.itangcent.idea.psi.PsiMethodResource
import com.itangcent.intellij.config.rule.RuleComputer
import com.itangcent.intellij.config.rule.computer
Expand Down Expand Up @@ -74,10 +74,10 @@ open class GenericMethodDocClassExporter : ClassExporter, Worker {
protected lateinit var methodDocBuilderListener: MethodDocBuilderListener

@Inject
protected val settingBinder: SettingBinder? = null
protected lateinit var supportSettingsHelper: SupportSettingsHelper

@Inject
protected val jsonSetting: JsonSetting? = null
protected lateinit var intelligentSettingsHelper: IntelligentSettingsHelper

@Inject
protected val duckTypeHelper: DuckTypeHelper? = null
Expand Down Expand Up @@ -329,7 +329,7 @@ open class GenericMethodDocClassExporter : ClassExporter, Worker {
) {
val paramType = param.getType() ?: return
val typeObject = psiClassHelper!!.getTypeObject(paramType, param.psi(),
jsonSetting!!.jsonOptionForInput(JsonOption.READ_COMMENT))
intelligentSettingsHelper.jsonOptionForInput(JsonOption.READ_COMMENT))
methodDocBuilderListener.addParam(methodExportContext, methodDoc, param.name(), typeObject, paramDesc, ruleComputer!!.computer(ClassExportRuleKeys.PARAM_REQUIRED, param) == true)
}

Expand All @@ -347,7 +347,7 @@ open class GenericMethodDocClassExporter : ClassExporter, Worker {
// actionContext!!.callWithTimeout(20000) { methodReturnInferHelper.inferReturn(method) }
}
else -> psiClassHelper!!.getTypeObject(duckType, methodExportContext.psi(),
jsonSetting!!.jsonOptionForOutput(JsonOption.READ_COMMENT))
intelligentSettingsHelper.jsonOptionForOutput(JsonOption.READ_COMMENT))
}
}

Expand All @@ -356,10 +356,10 @@ open class GenericMethodDocClassExporter : ClassExporter, Worker {
}

private fun methodDocEnable(): Boolean {
return settingBinder!!.read().methodDocEnable
return supportSettingsHelper.methodDocEnable()
}

private fun needInfer(): Boolean {
return settingBinder!!.read().inferEnable
return intelligentSettingsHelper.inferEnable()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import com.itangcent.idea.plugin.WorkerStatus
import com.itangcent.idea.plugin.api.export.MethodFilter
import com.itangcent.idea.plugin.api.export.core.*
import com.itangcent.idea.plugin.settings.SettingBinder
import com.itangcent.idea.plugin.settings.helper.SupportSettingsHelper
import com.itangcent.idea.psi.PsiMethodResource
import com.itangcent.intellij.config.rule.RuleComputer
import com.itangcent.intellij.context.ActionContext
Expand All @@ -28,6 +29,9 @@ open class SimpleGenericMethodDocClassExporter : ClassExporter, Worker {
@Inject
protected val jvmClassHelper: JvmClassHelper? = null

@Inject
protected lateinit var supportSettingsHelper: SupportSettingsHelper

override fun support(docType: KClass<*>): Boolean {
return docType == MethodDoc::class && methodDocEnable()
}
Expand Down Expand Up @@ -170,6 +174,6 @@ open class SimpleGenericMethodDocClassExporter : ClassExporter, Worker {
}

private fun methodDocEnable(): Boolean {
return settingBinder!!.read().methodDocEnable
return supportSettingsHelper.methodDocEnable()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import com.itangcent.common.model.Doc
import com.itangcent.idea.plugin.Worker
import com.itangcent.idea.plugin.api.export.core.ClassExporter
import com.itangcent.idea.plugin.settings.SettingBinder
import com.itangcent.idea.plugin.settings.helper.MarkdownSettingsHelper
import com.itangcent.idea.utils.Charsets
import com.itangcent.idea.utils.FileSaveHelper
import com.itangcent.intellij.context.ActionContext
Expand Down Expand Up @@ -37,7 +38,7 @@ class MarkdownApiExporter {
private val markdownFormatter: MarkdownFormatter? = null

@Inject
private val settingBinder: SettingBinder? = null
private lateinit var markdownSettingsHelper: MarkdownSettingsHelper

fun export() {

Expand All @@ -51,7 +52,7 @@ class MarkdownApiExporter {
val project = actionContext.instance(Project::class)
val yes = Messages.showYesNoDialog(project,
"Export the api in directory [${ActionUtils.findCurrentPath(dir)}]?",
"Are you sure",
"Please Confirm",
Messages.getQuestionIcon())
if (yes == Messages.YES) {
callBack(true)
Expand Down Expand Up @@ -83,8 +84,7 @@ class MarkdownApiExporter {
docs.clear()
actionContext!!.runAsync {
try {
fileSaveHelper!!.saveOrCopy(apiInfo, Charsets.forName(settingBinder!!.read().outputCharset)?.charset()
?: kotlin.text.Charsets.UTF_8, {
fileSaveHelper!!.saveOrCopy(apiInfo, markdownSettingsHelper.outputCharset(), {
logger.info("Exported data are copied to clipboard,you can paste to a md file now")
}, {
logger.info("Apis save success: $it")
Expand Down
Loading

0 comments on commit 43495e5

Please sign in to comment.