Skip to content

Commit 0f716db

Browse files
committed
Bypass SSL certificate checks (#435)
1 parent 4f86bfc commit 0f716db

File tree

4 files changed

+64
-9
lines changed

4 files changed

+64
-9
lines changed

resources/messages/GraphQLMessages.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ graphql.notification.introspection.spec.error.body=A valid schema could not be b
55
graphql.notification.introspection.parse.error=The server introspection response cannot be parsed as a valid JSON object.
66
graphql.notification.introspection.empty.errors=Encountered empty error array, which does not conform to the GraphQL spec.
77
graphql.notification.error.title=GraphQL error
8+
graphql.notification.ssl.cert.error.title=SSL certificate error
89
graphql.notification.stack.trace=Stack trace
910
graphql.notification.retry.without.defaults=Retry (skip default values from now on)
1011
graphql.notification.retry=Retry
@@ -18,6 +19,7 @@ graphql.notification.load.schema.from.endpoint.title=Get GraphQL schema from end
1819
graphql.notification.load.schema.from.endpoint.body=Introspect ''{0}'' to update the local schema file.
1920
graphql.notification.load.schema.from.endpoint.action=Introspect ''{0}''
2021
graphql.notification.dont.show.again.message=Don't show again
22+
graphql.notification.trust.all.hosts=Trust all hosts
2123

2224
# Introspection
2325
graphql.introspection.missing.data=Expected `data` key to be present in query result.

src/main/com/intellij/lang/jsgraphql/ide/editor/GraphQLIntrospectionService.java

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import com.intellij.openapi.application.WriteAction;
3232
import com.intellij.openapi.command.WriteCommandAction;
3333
import com.intellij.openapi.components.ServiceManager;
34+
import com.intellij.openapi.diagnostic.Logger;
3435
import com.intellij.openapi.fileEditor.FileEditor;
3536
import com.intellij.openapi.fileEditor.FileEditorManager;
3637
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
@@ -66,15 +67,23 @@
6667
import org.apache.http.client.methods.CloseableHttpResponse;
6768
import org.apache.http.client.methods.HttpPost;
6869
import org.apache.http.client.methods.HttpUriRequest;
70+
import org.apache.http.conn.ssl.NoopHostnameVerifier;
71+
import org.apache.http.conn.ssl.TrustAllStrategy;
6972
import org.apache.http.entity.ContentType;
7073
import org.apache.http.entity.StringEntity;
7174
import org.apache.http.impl.client.CloseableHttpClient;
75+
import org.apache.http.impl.client.HttpClientBuilder;
7276
import org.apache.http.impl.client.HttpClients;
77+
import org.apache.http.ssl.SSLContextBuilder;
7378
import org.apache.http.util.EntityUtils;
7479
import org.jetbrains.annotations.NotNull;
7580
import org.jetbrains.annotations.Nullable;
7681

7782
import java.io.IOException;
83+
import java.security.GeneralSecurityException;
84+
import java.security.KeyManagementException;
85+
import java.security.KeyStoreException;
86+
import java.security.NoSuchAlgorithmException;
7887
import java.util.Collection;
7988
import java.util.List;
8089
import java.util.Map;
@@ -83,9 +92,11 @@
8392
import static com.intellij.lang.jsgraphql.v1.ide.project.JSGraphQLLanguageUIProjectService.setHeadersFromOptions;
8493

8594
public class GraphQLIntrospectionService implements Disposable {
95+
private static final Logger LOG = Logger.getInstance(GraphQLIntrospectionService.class);
8696

8797
private static final Set<String> DEFAULT_DIRECTIVES = Sets.newHashSet("deprecated", "skip", "include", "specifiedBy");
8898
private static final String DISABLE_EMPTY_ERRORS_WARNING_KEY = "graphql.empty.errors.warning.disabled";
99+
public static final String GRAPHQL_TRUST_ALL_HOSTS = "graphql.trust.all.hosts";
89100

90101
private GraphQLIntrospectionTask latestIntrospection = null;
91102
private final Project myProject;
@@ -164,6 +175,27 @@ public static HttpPost createRequest(@NotNull GraphQLConfigVariableAwareEndpoint
164175
return request;
165176
}
166177

178+
@NotNull
179+
public CloseableHttpClient createHttpClient() throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException {
180+
HttpClientBuilder builder = HttpClients.custom();
181+
if (PropertiesComponent.getInstance(myProject).isTrueValue(GRAPHQL_TRUST_ALL_HOSTS)) {
182+
builder
183+
.setSSLContext(new SSLContextBuilder().loadTrustMaterial(null, TrustAllStrategy.INSTANCE).build())
184+
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE);
185+
}
186+
return builder.build();
187+
}
188+
189+
@Nullable
190+
public NotificationAction createTrustAllHostsAction() {
191+
final PropertiesComponent propertiesComponent = PropertiesComponent.getInstance(myProject);
192+
if (propertiesComponent.isTrueValue(GRAPHQL_TRUST_ALL_HOSTS)) return null;
193+
194+
return NotificationAction.createSimpleExpiring(
195+
GraphQLBundle.message("graphql.notification.trust.all.hosts"),
196+
() -> propertiesComponent.setValue(GRAPHQL_TRUST_ALL_HOSTS, true));
197+
}
198+
167199
public void addIntrospectionStackTraceAction(@NotNull Notification notification, @NotNull Exception exception) {
168200
notification.addAction(new NotificationAction(GraphQLBundle.message("graphql.notification.stack.trace")) {
169201
@Override
@@ -392,6 +424,7 @@ void createOrUpdateIntrospectionOutputFile(@NotNull String schemaText,
392424
}
393425
});
394426
} catch (IOException ioe) {
427+
LOG.warn(ioe);
395428
Notifications.Bus.notify(new Notification(
396429
GraphQLNotificationUtil.NOTIFICATION_GROUP_ID,
397430
GraphQLBundle.message("graphql.notification.error.title"),
@@ -457,10 +490,10 @@ public void run(@NotNull ProgressIndicator indicator) {
457490
indicator.setIndeterminate(true);
458491
String responseJson;
459492

460-
try (final CloseableHttpClient httpClient = HttpClients.createDefault();
493+
try (final CloseableHttpClient httpClient = createHttpClient();
461494
final CloseableHttpResponse response = httpClient.execute(request)) {
462495
responseJson = ObjectUtils.coalesce(EntityUtils.toString(response.getEntity()), "");
463-
} catch (IOException e) {
496+
} catch (IOException | GeneralSecurityException e) {
464497
GraphQLNotificationUtil.showGraphQLRequestErrorNotification(myProject, url, e, NotificationType.WARNING, retry);
465498
return;
466499
}

src/main/com/intellij/lang/jsgraphql/ide/notifications/GraphQLNotificationUtil.java

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22

33
import com.intellij.lang.jsgraphql.GraphQLBundle;
44
import com.intellij.lang.jsgraphql.GraphQLSettings;
5+
import com.intellij.lang.jsgraphql.ide.editor.GraphQLIntrospectionService;
56
import com.intellij.notification.Notification;
67
import com.intellij.notification.NotificationAction;
78
import com.intellij.notification.NotificationType;
89
import com.intellij.notification.Notifications;
910
import com.intellij.openapi.actionSystem.AnActionEvent;
1011
import com.intellij.openapi.application.ApplicationManager;
12+
import com.intellij.openapi.diagnostic.Logger;
1113
import com.intellij.openapi.fileEditor.FileEditorManager;
1214
import com.intellij.openapi.project.Project;
1315
import com.intellij.openapi.util.text.StringUtil;
@@ -17,7 +19,10 @@
1719
import org.jetbrains.annotations.NotNull;
1820
import org.jetbrains.annotations.Nullable;
1921

22+
import javax.net.ssl.SSLException;
23+
2024
public class GraphQLNotificationUtil {
25+
private static final Logger LOG = Logger.getInstance(GraphQLNotificationUtil.class);
2126
public static final String NOTIFICATION_GROUP_ID = "GraphQL";
2227

2328
public static void showInvalidConfigurationNotification(@NotNull String message,
@@ -46,16 +51,30 @@ public static void showGraphQLRequestErrorNotification(@NotNull Project project,
4651
@NotNull String url,
4752
@NotNull Exception error,
4853
@NotNull NotificationType notificationType,
49-
@Nullable NotificationAction retry) {
54+
@Nullable NotificationAction action) {
55+
LOG.warn(error);
56+
57+
boolean isSSLError = error instanceof SSLException;
58+
final String message = isSSLError
59+
? GraphQLBundle.message("graphql.notification.ssl.cert.error.title")
60+
: GraphQLBundle.message("graphql.notification.error.title");
61+
5062
Notification notification = new Notification(
5163
NOTIFICATION_GROUP_ID,
52-
GraphQLBundle.message("graphql.notification.error.title"),
64+
message,
5365
url + ": " + GraphQLNotificationUtil.formatExceptionMessage(error),
5466
notificationType
5567
);
5668

57-
if (retry != null) {
58-
notification.addAction(retry);
69+
if (isSSLError) {
70+
NotificationAction trustAction = GraphQLIntrospectionService.getInstance(project).createTrustAllHostsAction();
71+
if (trustAction != null) {
72+
notification.addAction(trustAction);
73+
}
74+
}
75+
76+
if (action != null) {
77+
notification.addAction(action);
5978
}
6079

6180
Notifications.Bus.notify(notification, project);

src/main/com/intellij/lang/jsgraphql/v1/ide/project/JSGraphQLLanguageUIProjectService.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@
7676
import org.apache.http.client.methods.CloseableHttpResponse;
7777
import org.apache.http.client.methods.HttpPost;
7878
import org.apache.http.impl.client.CloseableHttpClient;
79-
import org.apache.http.impl.client.HttpClients;
8079
import org.apache.http.util.EntityUtils;
8180
import org.jetbrains.annotations.NotNull;
8281

@@ -86,6 +85,7 @@
8685
import java.awt.event.MouseAdapter;
8786
import java.awt.event.MouseEvent;
8887
import java.io.IOException;
88+
import java.security.GeneralSecurityException;
8989
import java.util.Collection;
9090
import java.util.HashMap;
9191
import java.util.List;
@@ -396,8 +396,9 @@ public void run(@NotNull ProgressIndicator indicator) {
396396
}
397397

398398
private void runQuery(Editor editor, VirtualFile virtualFile, JSGraphQLQueryContext context, String url, HttpPost request) {
399+
GraphQLIntrospectionService introspectionService = GraphQLIntrospectionService.getInstance(myProject);
399400
try {
400-
try (final CloseableHttpClient httpClient = HttpClients.createDefault()) {
401+
try (final CloseableHttpClient httpClient = introspectionService.createHttpClient()) {
401402
editor.putUserData(JS_GRAPH_QL_EDITOR_QUERYING, true);
402403

403404
String responseJson;
@@ -453,7 +454,7 @@ private void runQuery(Editor editor, VirtualFile virtualFile, JSGraphQLQueryCont
453454
} finally {
454455
editor.putUserData(JS_GRAPH_QL_EDITOR_QUERYING, null);
455456
}
456-
} catch (IOException | IllegalArgumentException e) {
457+
} catch (IOException | GeneralSecurityException e) {
457458
GraphQLNotificationUtil.showGraphQLRequestErrorNotification(myProject, url, e, NotificationType.WARNING, null);
458459
}
459460
}

0 commit comments

Comments
 (0)