OPENIDE #79 Reimplement the external link filtering mechanism from OpenIDE

(cherry picked from commit 3f478908c068e5506ead6a71c0933d5696b4b4c0)
This commit is contained in:
Nikita Iarychenko
2025-02-27 19:03:31 +04:00
parent 8ffad6a9b5
commit e6871d4b28
10 changed files with 121 additions and 5 deletions

5
.idea/encodings.xml generated
View File

@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false">
<component name="Encoding" defaultCharsetForPropertiesFiles="UTF-8">
<file url="PROJECT" charset="UTF-8" />
</component>
</project>
</project>

View File

@@ -37,6 +37,8 @@
serviceImplementation="com.intellij.codeInsight.completion.BaseCompletionService"/>
<applicationService serviceInterface="com.intellij.ide.plugins.PluginUtil"
serviceImplementation="com.intellij.ide.plugins.PluginUtilImpl"/>
<applicationService serviceInterface="ru.openide.io.OpenIdePluginUtil"
serviceImplementation="com.intellij.util.OpenIdePluginUtilImpl"/>
<applicationService serviceInterface="com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceCompletion"
serviceImplementation="com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceCompletionImpl"/>
<applicationService serviceImplementation="com.intellij.find.impl.FindSettingsImpl$FindRecents"/>

View File

@@ -0,0 +1,20 @@
// Copyright (c) Haulmont 2025. All Rights Reserved.
// Use is subject to license terms.
package com.intellij.util
import com.intellij.ide.plugins.PluginManagerCore
import com.intellij.ide.plugins.PluginUtil
import com.intellij.openapi.extensions.PluginId
import ru.openide.io.OpenIdePluginUtil
class OpenIdePluginUtilImpl : OpenIdePluginUtil {
override fun findNonBundledPluginId(t: Throwable): PluginId? {
val pluginId = PluginUtil.getInstance().findPluginId(t) ?: return null
val idString = pluginId.idString
if (idString == "ru.openide.docker" || idString == "com.haulmont.amplicode") return pluginId
val pluginDescriptor = PluginManagerCore.getPlugin(pluginId) ?: return null
if (pluginDescriptor.isBundled) return null
return pluginId
}
}

View File

@@ -0,0 +1,4 @@
# Copyright (c) Haulmont 2025. All Rights Reserved.
# Use is subject to license terms.
access.to.untrusted.source=Access to an untrusted source
allow.access=Allow access

View File

@@ -0,0 +1,2 @@
access.to.untrusted.source=Доступ к неразрешенному источнику
allow.access=Разрешить доступ

View File

@@ -21,6 +21,8 @@ import com.intellij.util.Url;
import com.intellij.util.net.NetUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import ru.openide.io.StubUrlConnection;
import ru.openide.io.WhiteListUrls;
import javax.net.ssl.*;
import java.io.*;

View File

@@ -0,0 +1,19 @@
// Copyright (c) Haulmont 2025. All Rights Reserved.
// Use is subject to license terms.
package ru.openide.io
import com.intellij.DynamicBundle
import org.jetbrains.annotations.Nls
import org.jetbrains.annotations.NonNls
import org.jetbrains.annotations.PropertyKey
@NonNls
private const val BUNDLE = "messages.OpenIdeBundle"
object OpenIdeBundle {
private val INSTANCE = DynamicBundle(OpenIdeBundle::class.java, BUNDLE)
fun message(key: @PropertyKey(resourceBundle = BUNDLE) String, vararg params: Any): @Nls String {
return INSTANCE.getMessage(key, *params)
}
}

View File

@@ -0,0 +1,27 @@
// Copyright (c) Haulmont 2025. All Rights Reserved.
// Use is subject to license terms.
package ru.openide.io
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.*
import com.intellij.util.xmlb.annotations.CollectionBean
@Service(Service.Level.APP)
@State(name = "OpenIdePersistentUrlStorage", storages = [Storage("openIdeUrlStorage.xml")])
class OpenIdePersistentUrlStorage: SimplePersistentStateComponent<PersistentUrlStorageState>(PersistentUrlStorageState()) {
companion object {
fun getInstance(): OpenIdePersistentUrlStorage {
return ApplicationManager.getApplication().getService(OpenIdePersistentUrlStorage::class.java)
}
}
fun getUrls(): MutableList<String> {
return state.urls
}
}
class PersistentUrlStorageState : BaseState() {
@get:CollectionBean
val urls: MutableList<String> by list()
}

View File

@@ -0,0 +1,16 @@
// Copyright (c) Haulmont 2025. All Rights Reserved.
// Use is subject to license terms.
package ru.openide.io
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.extensions.PluginId
interface OpenIdePluginUtil {
companion object {
fun getInstance(): OpenIdePluginUtil {
return ApplicationManager.getApplication().getService(OpenIdePluginUtil::class.java)
}
}
fun findNonBundledPluginId(t: Throwable): PluginId?
}

View File

@@ -1,7 +1,10 @@
// Copyright (c) Haulmont 2024. All Rights Reserved.
// Use is subject to license terms.
package com.intellij.util.io
package ru.openide.io
import com.intellij.notification.Notification
import com.intellij.notification.NotificationAction
import com.intellij.notification.NotificationType
import java.net.URL
import java.net.URLConnection
@@ -171,7 +174,29 @@ object WhiteListUrls {
@JvmStatic
fun isAvailableUrl(url: String): Boolean {
return urls.startWith(url) || jsonSchemaUrls.startWith(url)
if (urls.startWith(url)
|| jsonSchemaUrls.startWith(url)
|| OpenIdePersistentUrlStorage.getInstance().getUrls().startWith(url)) {
return true
}
val findPluginId = OpenIdePluginUtil.getInstance().findNonBundledPluginId(Throwable())
if (findPluginId != null) {
return true
}
showAccessRequestNotification(url)
return false
}
private fun showAccessRequestNotification(url: String) {
val addUrlAction = NotificationAction.createSimpleExpiring(OpenIdeBundle.message("allow.access")) {
OpenIdePersistentUrlStorage.getInstance().getUrls().add(url)
}
Notification("Find Problems", OpenIdeBundle.message("access.to.untrusted.source"), url, NotificationType.WARNING)
.addAction(addUrlAction)
.notify(null)
}
private fun List<String>.startWith(url: String): Boolean {