From 70db8121b892f4e8e160745a1488b02462c74e8d Mon Sep 17 00:00:00 2001 From: Denis Rosa Date: Fri, 1 Dec 2023 18:38:00 +0000 Subject: [PATCH] adding ldap support --- .../intellij/database/ActiveCluster.java | 18 ++++++++++-- .../intellij/database/DataLoader.java | 21 ++++++++++++-- .../intellij/persistence/SavedCluster.java | 13 +++++++++ .../intellij/tree/NewConnectionDialog.java | 29 ++++++++++++++----- 4 files changed, 67 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/couchbase/intellij/database/ActiveCluster.java b/src/main/java/com/couchbase/intellij/database/ActiveCluster.java index 4995745d..f5658421 100644 --- a/src/main/java/com/couchbase/intellij/database/ActiveCluster.java +++ b/src/main/java/com/couchbase/intellij/database/ActiveCluster.java @@ -2,6 +2,7 @@ import com.couchbase.client.core.cnc.EventBus; import com.couchbase.client.core.cnc.events.endpoint.UnexpectedEndpointDisconnectedEvent; +import com.couchbase.client.core.env.PasswordAuthenticator; import com.couchbase.client.java.Cluster; import com.couchbase.client.java.ClusterOptions; import com.couchbase.intellij.database.entity.CouchbaseBucket; @@ -98,9 +99,20 @@ public void run(@NotNull ProgressIndicator indicator) { try { String password = DataLoader.getClusterPassword(savedCluster); + ClusterOptions options; + if (!savedCluster.getLDAP()) { + options = ClusterOptions.clusterOptions(savedCluster.getUsername(), password); + } else { + PasswordAuthenticator authenticator = PasswordAuthenticator.builder().username(savedCluster.getUsername()) + .password(password) + .onlyEnablePlainSaslMechanism().build(); + + options = ClusterOptions.clusterOptions(authenticator); + } + Cluster cluster = Cluster.connect(savedCluster.getUrl() - + (savedCluster.getQueryParams() ==null? "": savedCluster.getQueryParams() ), - ClusterOptions.clusterOptions(savedCluster.getUsername(), password).environment(env -> { + + (savedCluster.getQueryParams() == null ? "" : savedCluster.getQueryParams()), + options.environment(env -> { // env.applyProfile("wan-development"); })); @@ -154,7 +166,7 @@ public void run(@NotNull ProgressIndicator indicator) { //Notify Listeners that we connected to a new cluster. //NOTE: Only singletons can register here, otherwise we will get a memory leak CompletableFuture.runAsync(() -> { - for(Runnable run: newConnectionListener) { + for (Runnable run : newConnectionListener) { try { run.run(); } catch (Exception e) { diff --git a/src/main/java/com/couchbase/intellij/database/DataLoader.java b/src/main/java/com/couchbase/intellij/database/DataLoader.java index 5bec8c7b..d3d2072c 100644 --- a/src/main/java/com/couchbase/intellij/database/DataLoader.java +++ b/src/main/java/com/couchbase/intellij/database/DataLoader.java @@ -1,5 +1,6 @@ package com.couchbase.intellij.database; +import com.couchbase.client.core.env.PasswordAuthenticator; import com.couchbase.client.core.error.DocumentNotFoundException; import com.couchbase.client.core.error.IndexFailureException; import com.couchbase.client.core.error.PlanningFailureException; @@ -418,11 +419,24 @@ public static String adjustClusterProtocol(String cluster, boolean ssl) { return protocol + cluster; } - public static Set listBucketNames(String clusterUrl, boolean ssl, String username, String password) { + public static Set listBucketNames(String clusterUrl, boolean ssl, String username, String password, boolean ldap) { Cluster cluster = null; try { - cluster = Cluster.connect(adjustClusterProtocol(clusterUrl, ssl), ClusterOptions.clusterOptions(username, password).environment(env -> { + + ClusterOptions options; + + if (!ldap) { + options = ClusterOptions.clusterOptions(username, password); + } else { + PasswordAuthenticator authenticator = PasswordAuthenticator.builder().username(username) + .password(password) + .onlyEnablePlainSaslMechanism().build(); + + options = ClusterOptions.clusterOptions(authenticator); + } + + cluster = Cluster.connect(adjustClusterProtocol(clusterUrl, ssl), options.environment(env -> { //env.applyProfile("wan-development"); })); cluster.waitUntilReady(Duration.ofSeconds(5)); @@ -437,7 +451,7 @@ public static Set listBucketNames(String clusterUrl, boolean ssl, String } - public static SavedCluster saveDatabaseCredentials(String name, String url, String queryParams, boolean isSSL, String username, String password, String defaultBucket) { + public static SavedCluster saveDatabaseCredentials(String name, String url, String queryParams, boolean isSSL, String username, String password, String defaultBucket, Boolean ldap) { String key = username + ":" + name; SavedCluster sc = new SavedCluster(); sc.setId(key); @@ -447,6 +461,7 @@ public static SavedCluster saveDatabaseCredentials(String name, String url, Stri sc.setUsername(username); sc.setUrl(adjustClusterProtocol(url, isSSL)); sc.setDefaultBucket(defaultBucket); + sc.setLDAP(ldap); Clusters clusters = ClustersStorage.getInstance().getValue(); diff --git a/src/main/java/com/couchbase/intellij/persistence/SavedCluster.java b/src/main/java/com/couchbase/intellij/persistence/SavedCluster.java index bcf97263..f4e868fb 100644 --- a/src/main/java/com/couchbase/intellij/persistence/SavedCluster.java +++ b/src/main/java/com/couchbase/intellij/persistence/SavedCluster.java @@ -19,12 +19,25 @@ public class SavedCluster { private String color; private boolean sslEnable; + + private Boolean ldap; private String defaultBucket; private Boolean readOnly; private Long inferCachePeriod; + public Boolean getLDAP() { + if (ldap == null) { + return false; + } + return ldap; + } + + public void setLDAP(Boolean LDAP) { + ldap = LDAP; + } + public String getId() { return id; } diff --git a/src/main/java/com/couchbase/intellij/tree/NewConnectionDialog.java b/src/main/java/com/couchbase/intellij/tree/NewConnectionDialog.java index cf93d7ce..7483a36d 100644 --- a/src/main/java/com/couchbase/intellij/tree/NewConnectionDialog.java +++ b/src/main/java/com/couchbase/intellij/tree/NewConnectionDialog.java @@ -44,6 +44,7 @@ public class NewConnectionDialog extends DialogWrapper { private JBTextField connectionNameTextField; private JBTextField hostTextField; private JCheckBox enableSSLCheckBox; + private JCheckBox ldapAuthCheckbox; private JBTextField usernameTextField; private JPasswordField passwordField; private JButton testConnectionButton; @@ -55,7 +56,7 @@ public class NewConnectionDialog extends DialogWrapper { private JPasswordField apiSecretField; private JPanel wrapperPanel; - private DefaultMutableTreeNode clickedNode; + private DefaultMutableTreeNode clickedNode; public NewConnectionDialog(Project project, Tree tree, SavedCluster savedCluster, DefaultMutableTreeNode clickedNode) { super(false); @@ -159,7 +160,6 @@ private void handleSaveConnection() { } } catch (Exception ex) { Log.error(ex); - ex.printStackTrace(); showErrorLabel("Connection failed.
Please double-check your credentials" + (defaultBucketTextField.getText().trim().isEmpty() ? " or inform a Bucket on Advanced Settings -> Troubleshooting to inspect your connection" : "") + ""); saveButton.setEnabled(true); messageLabel.setText(""); @@ -168,11 +168,15 @@ private void handleSaveConnection() { try { - if(this.savedCluster != null) { + if (this.savedCluster != null) { ConnectionNodeDescriptor userObject = (ConnectionNodeDescriptor) clickedNode.getUserObject(); TreeActionHandler.deleteConnection(clickedNode, userObject, tree); } - SavedCluster sc = DataLoader.saveDatabaseCredentials(connectionNameTextField.getText(), getBaseUrl(hostTextField.getText()), getQueryParams(hostTextField.getText()), enableSSLCheckBox.isSelected(), usernameTextField.getText(), String.valueOf(passwordField.getPassword()), defaultBucketTextField.getText().trim().isEmpty() ? null : defaultBucketTextField.getText()); + SavedCluster sc = DataLoader.saveDatabaseCredentials(connectionNameTextField.getText(), + getBaseUrl(hostTextField.getText()), getQueryParams(hostTextField.getText()), + enableSSLCheckBox.isSelected(), usernameTextField.getText(), String.valueOf(passwordField.getPassword()), + defaultBucketTextField.getText().trim().isEmpty() ? null : defaultBucketTextField.getText(), + ldapAuthCheckbox.isSelected()); messageLabel.setText("Connection was successful"); TreeActionHandler.connectToCluster(project, sc, tree, null); close(DialogWrapper.CANCEL_EXIT_CODE); @@ -184,7 +188,6 @@ private void handleSaveConnection() { showErrorLabel("The Couchbase cluster URL and username already exists."); } catch (Exception ex) { Log.error(ex); - ex.printStackTrace(); messageLabel.setText(""); showErrorLabel("Could not save the database credentials"); } @@ -239,7 +242,9 @@ private void handleTestConnection() { } private boolean hasCorrectBucketConnection() { - Set buckets = DataLoader.listBucketNames(hostTextField.getText(), enableSSLCheckBox.isSelected(), usernameTextField.getText(), String.valueOf(passwordField.getPassword())); + Set buckets = DataLoader.listBucketNames(hostTextField.getText(), + enableSSLCheckBox.isSelected(), usernameTextField.getText(), + String.valueOf(passwordField.getPassword()), ldapAuthCheckbox.isSelected()); if (!defaultBucketTextField.getText().trim().isEmpty()) { if (!buckets.contains(defaultBucketTextField.getText())) { @@ -394,6 +399,7 @@ private JPanel createDatabasePanel() { hostTextField = new JBTextField(30); hostTextField.getEmptyText().setText("Your cluster URL"); enableSSLCheckBox = new JCheckBox("Enable SSL"); + ldapAuthCheckbox = new JCheckBox("LDAP Auth"); gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridwidth = GridBagConstraints.REMAINDER; @@ -427,14 +433,21 @@ private JPanel createDatabasePanel() { gbc.gridy = 3; gbc.gridx = 1; gbc.weightx = 0.7; - firstPanel.add(TemplateUtil.createComponentWithBalloon(enableSSLCheckBox, "Check this if TLS is enabled in your cluster. If you specify 'couchbases://' protocol in your Connection String, this option will be checked automatically"), gbc); + JPanel checkboxPanel = new JPanel(); + checkboxPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); + checkboxPanel.add(TemplateUtil.createComponentWithBalloon(enableSSLCheckBox, "Check this if TLS is enabled in your cluster. If you specify 'couchbases://' protocol in your Connection String, this option will be checked automatically")); + JBPanel ldapPanel = TemplateUtil.createComponentWithBalloon(ldapAuthCheckbox, "Check this if your authentication uses LDAP"); + ldapPanel.setBorder(JBUI.Borders.emptyLeft(10)); + checkboxPanel.add(ldapPanel); + firstPanel.add(checkboxPanel, gbc); if (this.savedCluster != null) { connectionNameTextField.setText(this.savedCluster.getName()); hostTextField.setText(this.savedCluster.getUrl()); enableSSLCheckBox.setSelected(this.savedCluster.isSslEnable()); + ldapAuthCheckbox.setSelected(this.savedCluster.getLDAP()); cleanURL(); - hostTextField.setText(hostTextField.getText()+ (savedCluster.getQueryParams()!=null?savedCluster.getQueryParams(): "")); + hostTextField.setText(hostTextField.getText() + (savedCluster.getQueryParams() != null ? savedCluster.getQueryParams() : "")); } return firstPanel;