Skip to content

Commit 9d93a84

Browse files
committed
Merge pull request RedisInsight#3350 from uglide/feature/ssl
Add SSL support
2 parents 9b746c8 + 6706d12 commit 9d93a84

File tree

7 files changed

+288
-31
lines changed

7 files changed

+288
-31
lines changed

src/app/dialogs/connect.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ ConnectionWindow::ConnectionWindow(QWeakPointer<ConnectionsManager> manager, QWi
2020
// connect slots to signals
2121
connect(ui.okButton, SIGNAL(clicked()), this, SLOT(OnOkButtonClick()));
2222
connect(ui.selectPrivateKeyPath, SIGNAL(clicked()), this, SLOT(OnBrowseSshKeyClick()));
23+
connect(ui.sslCACertButton, &QPushButton::clicked, this, [this]() {
24+
OnBrowsePemFileClick(ui.sslCACertEdit);
25+
});
2326
connect(ui.testConnectionButton, SIGNAL(clicked()), this, SLOT(OnTestConnectionButtonClick()));
2427
connect(ui.showPasswordCheckbox, SIGNAL(stateChanged(int)), this, SLOT(OnShowPasswordCheckboxChanged(int)));
2528

@@ -70,6 +73,11 @@ void ConnectionWindow::loadValuesFromConfig(const RedisClient::ConnectionConfig&
7073
ui.sshKeysGroup->setChecked(true);
7174
}
7275
}
76+
77+
if (config.useSsl()) {
78+
ui.useSsl->setCheckState(Qt::Checked);
79+
ui.sslCACertEdit->setText(config.param<QString>("ssl_ca_cert_path"));
80+
}
7381
}
7482

7583
void ConnectionWindow::markFieldInvalid(QWidget* w)
@@ -127,6 +135,16 @@ void ConnectionWindow::OnBrowseSshKeyClick()
127135
ui.privateKeyPath->setText(fileName);
128136
}
129137

138+
void ConnectionWindow::OnBrowsePemFileClick(QLineEdit* target)
139+
{
140+
QString fileName = QFileDialog::getOpenFileName(this, "Select PEM file", "", tr("All Files (*.pem)"));
141+
142+
if (fileName.isEmpty())
143+
return;
144+
145+
target->setText(fileName);
146+
}
147+
130148
void ConnectionWindow::OnTestConnectionButtonClick()
131149
{
132150
ui.validationWarning->hide();
@@ -248,6 +266,11 @@ bool ConnectionWindow::isSshTunnelUsed()
248266
return ui.useSshTunnel->checkState() == Qt::Checked;
249267
}
250268

269+
bool ConnectionWindow::isSslUsed()
270+
{
271+
return ui.useSsl->checkState() == Qt::Checked;
272+
}
273+
251274
RedisClient::ConnectionConfig ConnectionWindow::getConectionConfigFromFormData()
252275
{
253276
RedisClient::ConnectionConfig conf(ui.hostEdit->text().trimmed(),
@@ -273,5 +296,9 @@ RedisClient::ConnectionConfig ConnectionWindow::getConectionConfigFromFormData()
273296
(ui.sshKeysGroup->isChecked() ? ui.privateKeyPath->text().trimmed() : ""));
274297
}
275298

299+
if (isSslUsed()) {
300+
conf.setParam("ssl_ca_cert_path", ui.sslCACertEdit->text());
301+
}
302+
276303
return conf;
277304
}

src/app/dialogs/connect.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class ConnectionWindow : public QDialog
2727
bool isSshSettingsValid();
2828
bool isAdvancedSettingsValid();
2929
bool isSshTunnelUsed();
30+
bool isSslUsed();
3031

3132
void loadValuesFromConfig(const RedisClient::ConnectionConfig& config);
3233

@@ -37,5 +38,6 @@ private slots:
3738
void OnOkButtonClick();
3839
void OnShowPasswordCheckboxChanged(int);
3940
void OnBrowseSshKeyClick();
41+
void OnBrowsePemFileClick(QLineEdit *target);
4042
void OnTestConnectionButtonClick();
4143
};

src/app/forms/connection.ui

Lines changed: 149 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -46,18 +46,11 @@
4646
<property name="modal">
4747
<bool>true</bool>
4848
</property>
49-
<layout class="QGridLayout" name="gridLayout_5">
49+
<layout class="QVBoxLayout" name="verticalLayout">
5050
<property name="sizeConstraint">
5151
<enum>QLayout::SetMaximumSize</enum>
5252
</property>
53-
<item row="1" column="0">
54-
<widget class="QLabel" name="validationWarning">
55-
<property name="text">
56-
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;:/images/alert.png&quot;/&gt; Invalid settings detected&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
57-
</property>
58-
</widget>
59-
</item>
60-
<item row="0" column="0">
53+
<item>
6154
<widget class="QTabWidget" name="tabs">
6255
<property name="tabPosition">
6356
<enum>QTabWidget::North</enum>
@@ -73,14 +66,22 @@
7366
</property>
7467
<widget class="QWidget" name="mainTab">
7568
<attribute name="title">
76-
<string>Connection Settings</string>
69+
<string>Connection</string>
7770
</attribute>
7871
<layout class="QGridLayout" name="gridLayout">
7972
<item row="1" column="1">
80-
<widget class="QLineEdit" name="hostEdit"/>
73+
<widget class="QLineEdit" name="hostEdit">
74+
<property name="placeholderText">
75+
<string>redis-server host</string>
76+
</property>
77+
</widget>
8178
</item>
8279
<item row="3" column="1">
83-
<widget class="QLineEdit" name="authEdit"/>
80+
<widget class="QLineEdit" name="authEdit">
81+
<property name="placeholderText">
82+
<string>(Optional) redis-server authentication password</string>
83+
</property>
84+
</widget>
8485
</item>
8586
<item row="0" column="0">
8687
<widget class="QLabel" name="lbName">
@@ -90,7 +91,11 @@
9091
</widget>
9192
</item>
9293
<item row="0" column="1">
93-
<widget class="QLineEdit" name="nameEdit"/>
94+
<widget class="QLineEdit" name="nameEdit">
95+
<property name="placeholderText">
96+
<string>Connection name</string>
97+
</property>
98+
</widget>
9499
</item>
95100
<item row="1" column="0">
96101
<widget class="QLabel" name="lbHost">
@@ -137,6 +142,128 @@
137142
</item>
138143
</layout>
139144
</widget>
145+
<widget class="QWidget" name="sslTab">
146+
<attribute name="title">
147+
<string>SSL</string>
148+
</attribute>
149+
<layout class="QGridLayout" name="gridLayout_5">
150+
<item row="1" column="1">
151+
<widget class="QLineEdit" name="sslCACertEdit">
152+
<property name="placeholderText">
153+
<string>Public key in PEM format</string>
154+
</property>
155+
</widget>
156+
</item>
157+
<item row="3" column="1">
158+
<widget class="QLineEdit" name="sslLocalCertEdit">
159+
<property name="placeholderText">
160+
<string>(Optional) Authority in PEM format</string>
161+
</property>
162+
</widget>
163+
</item>
164+
<item row="2" column="1">
165+
<widget class="QLineEdit" name="sslPrivateKeyEdit">
166+
<property name="placeholderText">
167+
<string>(Optional) Private key in PEM format</string>
168+
</property>
169+
</widget>
170+
</item>
171+
<item row="1" column="0">
172+
<widget class="QLabel" name="sslPublicKey">
173+
<property name="sizePolicy">
174+
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
175+
<horstretch>0</horstretch>
176+
<verstretch>0</verstretch>
177+
</sizepolicy>
178+
</property>
179+
<property name="baseSize">
180+
<size>
181+
<width>80</width>
182+
<height>0</height>
183+
</size>
184+
</property>
185+
<property name="text">
186+
<string>Public Key:</string>
187+
</property>
188+
</widget>
189+
</item>
190+
<item row="3" column="0">
191+
<widget class="QLabel" name="label_2">
192+
<property name="sizePolicy">
193+
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
194+
<horstretch>0</horstretch>
195+
<verstretch>0</verstretch>
196+
</sizepolicy>
197+
</property>
198+
<property name="text">
199+
<string>Authority:</string>
200+
</property>
201+
</widget>
202+
</item>
203+
<item row="2" column="0">
204+
<widget class="QLabel" name="sslPrivateKey">
205+
<property name="sizePolicy">
206+
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
207+
<horstretch>0</horstretch>
208+
<verstretch>0</verstretch>
209+
</sizepolicy>
210+
</property>
211+
<property name="text">
212+
<string>Private key:</string>
213+
</property>
214+
</widget>
215+
</item>
216+
<item row="1" column="2">
217+
<widget class="QPushButton" name="sslCACertButton">
218+
<property name="maximumSize">
219+
<size>
220+
<width>60</width>
221+
<height>16777215</height>
222+
</size>
223+
</property>
224+
<property name="text">
225+
<string>...</string>
226+
</property>
227+
</widget>
228+
</item>
229+
<item row="2" column="2">
230+
<widget class="QPushButton" name="sslPrivateKeyButton">
231+
<property name="maximumSize">
232+
<size>
233+
<width>60</width>
234+
<height>16777215</height>
235+
</size>
236+
</property>
237+
<property name="text">
238+
<string>...</string>
239+
</property>
240+
</widget>
241+
</item>
242+
<item row="3" column="2">
243+
<widget class="QPushButton" name="sslLocalCertButton">
244+
<property name="maximumSize">
245+
<size>
246+
<width>60</width>
247+
<height>16777215</height>
248+
</size>
249+
</property>
250+
<property name="text">
251+
<string>...</string>
252+
</property>
253+
</widget>
254+
</item>
255+
<item row="0" column="0" colspan="3">
256+
<widget class="QCheckBox" name="useSsl">
257+
<property name="layoutDirection">
258+
<enum>Qt::LeftToRight</enum>
259+
</property>
260+
<property name="text">
261+
<string>Use SSL Protocol</string>
262+
</property>
263+
</widget>
264+
</item>
265+
</layout>
266+
</widget>
140267
<widget class="QWidget" name="sshTab">
141268
<attribute name="title">
142269
<string>SSH Tunnel</string>
@@ -245,7 +372,7 @@
245372
<item row="0" column="2">
246373
<widget class="QPushButton" name="selectPrivateKeyPath">
247374
<property name="text">
248-
<string>Browse</string>
375+
<string>...</string>
249376
</property>
250377
</widget>
251378
</item>
@@ -339,7 +466,14 @@
339466
</widget>
340467
</widget>
341468
</item>
342-
<item row="2" column="0">
469+
<item>
470+
<widget class="QLabel" name="validationWarning">
471+
<property name="text">
472+
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;:/images/alert.png&quot;/&gt; Invalid settings detected&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
473+
</property>
474+
</widget>
475+
</item>
476+
<item>
343477
<layout class="QHBoxLayout" name="DialogButtons">
344478
<property name="spacing">
345479
<number>6</number>

src/modules/redisclient/connectionconfig.cpp

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,25 @@ int RedisClient::ConnectionConfig::connectionTimeout() const
5353
return param<int>("timeout_connect");
5454
}
5555

56+
QList<QSslCertificate> RedisClient::ConnectionConfig::sslCaCertificates() const
57+
{
58+
QString path = param<QString>("ssl_ca_cert_path");
59+
if (!path.isEmpty() && QFile::exists(path))
60+
return QSslCertificate::fromPath(path);
61+
62+
return QList<QSslCertificate>();
63+
}
64+
65+
QString RedisClient::ConnectionConfig::sslPrivateKeyPath() const
66+
{
67+
return getValidPathFromParameter("ssl_private_key_path");
68+
}
69+
70+
QString RedisClient::ConnectionConfig::sslLocalCertPath() const
71+
{
72+
return getValidPathFromParameter("ssl_local_cert_path");
73+
}
74+
5675
bool RedisClient::ConnectionConfig::isSshPasswordUsed()
5776
{
5877
return !param<QString>("ssh_password").isEmpty();
@@ -93,6 +112,11 @@ bool RedisClient::ConnectionConfig::useAuth() const
93112
return !param<QString>("auth").isEmpty();
94113
}
95114

115+
bool RedisClient::ConnectionConfig::useSsl() const
116+
{
117+
return !param<QString>("ssl_ca_cert_path").isEmpty();
118+
}
119+
96120
bool RedisClient::ConnectionConfig::isValid() const
97121
{
98122
return isNull() == false
@@ -112,11 +136,7 @@ QWeakPointer<RedisClient::Connection> RedisClient::ConnectionConfig::getOwner()
112136

113137
QString RedisClient::ConnectionConfig::getSshPrivateKey()
114138
{
115-
QString path = param<QString>("ssh_private_key_path");
116-
if (path.isEmpty() || !QFile::exists(path))
117-
return QString();
118-
119-
return path;
139+
return getValidPathFromParameter("ssh_private_key_path");
120140
}
121141

122142
QString RedisClient::ConnectionConfig::keysPattern() const
@@ -145,6 +165,9 @@ RedisClient::ConnectionConfig RedisClient::ConnectionConfig::fromXml(QDomNode &
145165
valueMapping.insert("sshPassword", "ssh_password");
146166
valueMapping.insert("sshPort", "ssh_port");
147167
valueMapping.insert("sshPrivateKey", "ssh_private_key_path");
168+
valueMapping.insert("ssl_ca_cert_path", "");
169+
valueMapping.insert("ssl_private_key_path", "");
170+
valueMapping.insert("ssl_local_cert_path", "");
148171
valueMapping.insert("namespaceSeparator", "namespace_separator");
149172
valueMapping.insert("connectionTimeout", "timeout_connect");
150173
valueMapping.insert("executeTimeout", "timeout_execute");
@@ -212,6 +235,12 @@ QDomElement RedisClient::ConnectionConfig::toXml()
212235
saveXmlAttribute(dom, xml, "sshPrivateKey", param<QString>("ssh_private_key_path"));
213236
}
214237

238+
if (useSsl()) {
239+
saveXmlAttribute(dom, xml, "ssl_ca_cert_path", param<QString>("ssl_ca_cert_path"));
240+
saveXmlAttribute(dom, xml, "ssl_private_key_path", param<QString>("ssl_private_key_path"));
241+
saveXmlAttribute(dom, xml, "ssl_local_cert_path", param<QString>("ssl_local_cert_path"));
242+
}
243+
215244
return xml;
216245
}
217246

@@ -221,3 +250,12 @@ void RedisClient::ConnectionConfig::saveXmlAttribute(QDomDocument & document, QD
221250
attr.setValue(value);
222251
root.setAttributeNode(attr);
223252
}
253+
254+
QString RedisClient::ConnectionConfig::getValidPathFromParameter(const QString &name) const
255+
{
256+
QString path = param<QString>(name);
257+
if (path.isEmpty() || !QFile::exists(path))
258+
return QString();
259+
260+
return path;
261+
}

0 commit comments

Comments
 (0)