diff --git a/.idea/encodings.xml b/.idea/encodings.xml index 0218f4cb8c83..c2bae49d78cd 100644 --- a/.idea/encodings.xml +++ b/.idea/encodings.xml @@ -1,7 +1,6 @@ - + - - + \ No newline at end of file diff --git a/platform/analysis-impl/resources/META-INF/AnalysisImpl.xml b/platform/analysis-impl/resources/META-INF/AnalysisImpl.xml index a9a5013ba539..a49c627f3d8d 100644 --- a/platform/analysis-impl/resources/META-INF/AnalysisImpl.xml +++ b/platform/analysis-impl/resources/META-INF/AnalysisImpl.xml @@ -37,6 +37,8 @@ serviceImplementation="com.intellij.codeInsight.completion.BaseCompletionService"/> + diff --git a/platform/ide-core-impl/src/com/intellij/util/OpenIdePluginUtilImpl.kt b/platform/ide-core-impl/src/com/intellij/util/OpenIdePluginUtilImpl.kt new file mode 100644 index 000000000000..4c32ac1688c0 --- /dev/null +++ b/platform/ide-core-impl/src/com/intellij/util/OpenIdePluginUtilImpl.kt @@ -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 + } +} \ No newline at end of file diff --git a/platform/ide-core/resources/messages/OpenIdeBundle.properties b/platform/ide-core/resources/messages/OpenIdeBundle.properties new file mode 100644 index 000000000000..407ee845f5dc --- /dev/null +++ b/platform/ide-core/resources/messages/OpenIdeBundle.properties @@ -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 \ No newline at end of file diff --git a/platform/ide-core/resources/messages/OpenIdeBundle_ru_RU.properties b/platform/ide-core/resources/messages/OpenIdeBundle_ru_RU.properties new file mode 100644 index 000000000000..a0156964d643 --- /dev/null +++ b/platform/ide-core/resources/messages/OpenIdeBundle_ru_RU.properties @@ -0,0 +1,2 @@ +access.to.untrusted.source=Доступ к неразрешенному источнику +allow.access=Разрешить доступ \ No newline at end of file diff --git a/platform/ide-core/src/com/intellij/util/io/HttpRequests.java b/platform/ide-core/src/com/intellij/util/io/HttpRequests.java index ed95e9cf75d1..76e70fbaa1e0 100644 --- a/platform/ide-core/src/com/intellij/util/io/HttpRequests.java +++ b/platform/ide-core/src/com/intellij/util/io/HttpRequests.java @@ -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.*; diff --git a/platform/ide-core/src/ru/openide/io/OpenIdeBundle.kt b/platform/ide-core/src/ru/openide/io/OpenIdeBundle.kt new file mode 100644 index 000000000000..a217a373553c --- /dev/null +++ b/platform/ide-core/src/ru/openide/io/OpenIdeBundle.kt @@ -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) + } +} \ No newline at end of file diff --git a/platform/ide-core/src/ru/openide/io/OpenIdePersistentUrlStorage.kt b/platform/ide-core/src/ru/openide/io/OpenIdePersistentUrlStorage.kt new file mode 100644 index 000000000000..b1fdab2923db --- /dev/null +++ b/platform/ide-core/src/ru/openide/io/OpenIdePersistentUrlStorage.kt @@ -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()) { + + companion object { + fun getInstance(): OpenIdePersistentUrlStorage { + return ApplicationManager.getApplication().getService(OpenIdePersistentUrlStorage::class.java) + } + } + + fun getUrls(): MutableList { + return state.urls + } +} + +class PersistentUrlStorageState : BaseState() { + @get:CollectionBean + val urls: MutableList by list() +} \ No newline at end of file diff --git a/platform/ide-core/src/ru/openide/io/OpenIdePluginUtil.kt b/platform/ide-core/src/ru/openide/io/OpenIdePluginUtil.kt new file mode 100644 index 000000000000..f4fe5ba51aa3 --- /dev/null +++ b/platform/ide-core/src/ru/openide/io/OpenIdePluginUtil.kt @@ -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? +} \ No newline at end of file diff --git a/platform/ide-core/src/com/intellij/util/io/WhiteListUrls.kt b/platform/ide-core/src/ru/openide/io/WhiteListUrls.kt similarity index 90% rename from platform/ide-core/src/com/intellij/util/io/WhiteListUrls.kt rename to platform/ide-core/src/ru/openide/io/WhiteListUrls.kt index ffbcc7e5d2f2..1829f537cc64 100644 --- a/platform/ide-core/src/com/intellij/util/io/WhiteListUrls.kt +++ b/platform/ide-core/src/ru/openide/io/WhiteListUrls.kt @@ -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.startWith(url: String): Boolean {