11#include <config-libkleo.h>
13#include "editdirectoryservicedialog.h"
15#include <libkleo/algorithm.h>
16#include <libkleo/gnupg.h>
17#include <libkleo/keyserverconfig.h>
19#include <KCollapsibleGroupBox>
20#include <KConfigGroup>
22#include <KLocalizedString>
23#include <KPasswordLineEdit>
24#include <KSharedConfig>
25#include <KStandardGuiItem>
27#include <QButtonGroup>
29#include <QDialogButtonBox>
35#include <QRadioButton>
43int defaultPort(KeyserverConnection connection)
45 return connection == KeyserverConnection::TunnelThroughTLS ? 636 : 389;
49class EditDirectoryServiceDialog::Private
51 EditDirectoryServiceDialog *
const q;
56 QCheckBox *useDefaultPortCheckBox =
nullptr;
79#define SET_OBJECT_NAME(x) x->setObjectName(QStringLiteral(#x));
80 SET_OBJECT_NAME(hostEdit)
81 SET_OBJECT_NAME(portSpinBox)
82 SET_OBJECT_NAME(useDefaultPortCheckBox)
83 SET_OBJECT_NAME(authenticationGroup)
84 SET_OBJECT_NAME(userEdit)
85 SET_OBJECT_NAME(passwordEdit)
86 SET_OBJECT_NAME(connectionGroup)
87 SET_OBJECT_NAME(advancedSettings)
88 SET_OBJECT_NAME(baseDnEdit)
89 SET_OBJECT_NAME(additionalFlagsEdit)
90 SET_OBJECT_NAME(buttonBox)
97 layout->setColumnStretch(2, 1);
100 hostEdit->
setToolTip(
i18nc(
"@info:tooltip",
"Enter the name or IP address of the server hosting the directory service."));
105 portSpinBox->
setRange(1, USHRT_MAX);
107 "<b>(Optional, the default is fine in most cases)</b> "
108 "Pick the port number the directory service is listening on."));
110 useDefaultPortCheckBox->
setText(
i18n(
"Use default"));
114 mainLayout->addWidget(serverWidget);
121 radioButton->setToolTip(
i18nc(
"@info:tooltip",
"Use an anonymous LDAP server that does not require authentication."));
122 radioButton->setChecked(
true);
123 authenticationGroup->
addButton(radioButton,
static_cast<int>(KeyserverAuthentication::Anonymous));
127 auto radioButton =
new QRadioButton{
i18n(
"Authenticate via Active Directory")};
128 if (!engineIsVersion(2, 2, 28, GpgME::GpgSMEngine)) {
129 radioButton->setText(
i18n(
"Authenticate via Active Directory (requires GnuPG 2.2.28 or later)"));
131 radioButton->setToolTip(
132 i18nc(
"@info:tooltip",
"On Windows, authenticate to the LDAP server using the Active Directory with the current user."));
133 authenticationGroup->
addButton(radioButton,
static_cast<int>(KeyserverAuthentication::ActiveDirectory));
137 auto radioButton =
new QRadioButton{
i18n(
"Authenticate with user and password")};
138 radioButton->setToolTip(
i18nc(
"@info:tooltip",
"Authenticate to the LDAP server with your LDAP credentials."));
139 authenticationGroup->
addButton(radioButton,
static_cast<int>(KeyserverAuthentication::Password));
146 layout->setColumnStretch(1, 1);
149 userEdit->
setToolTip(
i18nc(
"@info:tooltip",
"Enter your LDAP user resp. Bind DN for authenticating to the LDAP server."));
155 "Enter your password for authenticating to the LDAP server.<nl/>"
156 "<warning>The password will be saved in the clear "
157 "in a configuration file in your home directory.</warning>"));
163 mainLayout->addWidget(authenticationWidget);
166 if (!engineIsVersion(2, 2, 28, GpgME::GpgSMEngine)) {
167 securityWidget->setTitle(
i18n(
"Connection Security (requires GnuPG 2.2.28 or later)"));
172 auto radioButton =
new QRadioButton{
i18n(
"Use default connection (probably not TLS secured)")};
173 radioButton->setToolTip(
i18nc(
"@info:tooltip",
174 "Use GnuPG's default to connect to the LDAP server. "
175 "By default, GnuPG 2.3 and earlier use a plain, not TLS secured connection. "
176 "<b>(Not recommended)</b>"));
177 radioButton->setChecked(
true);
178 connectionGroup->
addButton(radioButton,
static_cast<int>(KeyserverConnection::Default));
182 auto radioButton =
new QRadioButton{
i18n(
"Do not use a TLS secured connection")};
183 radioButton->setToolTip(
i18nc(
"@info:tooltip",
184 "Use a plain, not TLS secured connection to connect to the LDAP server. "
185 "<b>(Not recommended)</b>"));
186 connectionGroup->
addButton(radioButton,
static_cast<int>(KeyserverConnection::Plain));
191 radioButton->setToolTip(
i18nc(
"@info:tooltip",
192 "Use a standard TLS secured connection (initiated with STARTTLS) "
193 "to connect to the LDAP server. "
194 "<b>(Recommended)</b>"));
195 connectionGroup->
addButton(radioButton,
static_cast<int>(KeyserverConnection::UseSTARTTLS));
199 auto radioButton =
new QRadioButton{
i18n(
"Tunnel LDAP through a TLS connection")};
200 radioButton->setToolTip(
i18nc(
"@info:tooltip",
201 "Use a TLS secured connection through which the connection to the "
202 "LDAP server is tunneled. "
203 "<b>(Not recommended)</b>"));
204 connectionGroup->
addButton(radioButton,
static_cast<int>(KeyserverConnection::TunnelThroughTLS));
208 mainLayout->addWidget(securityWidget);
213 layout->setColumnStretch(1, 1);
217 "<b>(Optional, can usually be left empty)</b> "
218 "Enter the base DN for this LDAP server to limit searches "
219 "to only that subtree of the directory."));
225 "Here you can enter additional flags that are not yet (or no longer) "
226 "supported by Kleopatra. For example, older versions of GnuPG use "
227 "<code>ldaps</code> to request a TLS secured connection."));
231 mainLayout->addWidget(advancedSettings);
233 mainLayout->addStretch(1);
239 mainLayout->addWidget(buttonBox);
245 return ui.hostEdit->
text().trimmed();
250 return ui.useDefaultPortCheckBox->
isChecked() ? -1 : ui.portSpinBox->
value();
253 KeyserverAuthentication authentication()
const
255 return KeyserverAuthentication{ui.authenticationGroup->
checkedId()};
260 return ui.userEdit->
text().trimmed();
268 KeyserverConnection connection()
const
270 return KeyserverConnection{ui.connectionGroup->
checkedId()};
275 return ui.baseDnEdit->
text().trimmed();
281 return flag.trimmed();
285 bool inputIsAcceptable()
const
287 const bool hostIsSet = !host().
isEmpty();
288 const bool requiredCredentialsAreSet = authentication() != KeyserverAuthentication::Password || (!user().
isEmpty() && !password().
isEmpty());
289 return hostIsSet && requiredCredentialsAreSet;
295 if (ui.useDefaultPortCheckBox->
isChecked()) {
296 ui.portSpinBox->
setValue(defaultPort(connection()));
299 ui.userEdit->
setEnabled(authentication() == KeyserverAuthentication::Password);
300 ui.passwordEdit->
setEnabled(authentication() == KeyserverAuthentication::Password);
306 Private(EditDirectoryServiceDialog *q)
322 connect(ui.passwordEdit, &KPasswordLineEdit::passwordChanged, q, [
this]() {
342 void setKeyserver(
const KeyserverConfig &keyserver)
344 ui.hostEdit->
setText(keyserver.host());
345 ui.useDefaultPortCheckBox->
setChecked(keyserver.port() == -1);
346 ui.portSpinBox->
setValue(keyserver.port() == -1 ? defaultPort(keyserver.connection()) : keyserver.port());
347 ui.authenticationGroup->
button(
static_cast<int>(keyserver.authentication()))->
setChecked(
true);
348 ui.userEdit->
setText(keyserver.user());
349 ui.passwordEdit->
setPassword(keyserver.password());
350 ui.connectionGroup->
button(
static_cast<int>(keyserver.connection()))->
setChecked(
true);
351 ui.baseDnEdit->
setText(keyserver.ldapBaseDn());
354 ui.advancedSettings->
setExpanded(!keyserver.ldapBaseDn().
isEmpty() || !keyserver.additionalFlags().empty());
358 KeyserverConfig keyserver()
const
360 KeyserverConfig keyserver;
361 keyserver.setHost(host());
362 keyserver.setPort(port());
363 keyserver.setAuthentication(authentication());
364 keyserver.setUser(user());
365 keyserver.setPassword(password());
366 keyserver.setConnection(connection());
367 keyserver.setLdapBaseDn(baseDn());
368 keyserver.setAdditionalFlags(additionalFlags());
377 configGroup.writeEntry(
"Size", q->
size());
384 const auto size = configGroup.readEntry(
"Size",
QSize{});
385 if (
size.isValid()) {
393 , d{
std::make_unique<Private>(this)}
395 setWindowTitle(
i18nc(
"@title:window",
"Edit Directory Service"));
398EditDirectoryServiceDialog::~EditDirectoryServiceDialog() =
default;
400void EditDirectoryServiceDialog::setKeyserver(
const KeyserverConfig &keyserver)
402 d->setKeyserver(keyserver);
405KeyserverConfig EditDirectoryServiceDialog::keyserver()
const
407 return d->keyserver();
410#include "moc_editdirectoryservicedialog.cpp"
void setTitle(const QString &title)
void setExpanded(bool expanded)
static void assign(QPushButton *button, const KGuiItem &item)
void setPassword(const QString &password)
void setClearButtonEnabled(bool clear)
static KSharedConfig::Ptr openStateConfig(const QString &fileName=QString())
QString xi18nc(const char *context, const char *text, const TYPE &arg...)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
void setText(const QString &text)
void textEdited(const QString &text)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QObject * parent() const const
void setRange(int minimum, int maximum)
bool isEmpty() const const