QGIS API Documentation 4.1.0-Master (5bf3c20f3c9)
Loading...
Searching...
No Matches
qgsauthconfigselect.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsauthconfigselect.cpp
3 ---------------------
4 begin : October 5, 2014
5 copyright : (C) 2014 by Boundless Spatial, Inc. USA
6 author : Larry Shaffer
7 email : lshaffer at boundlessgeo dot com
8 ***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
16
17#include "ui_qgsauthconfigselect.h"
18#include "qgsauthconfigselect.h"
19
20#include "qgsapplication.h"
21#include "qgsauthconfig.h"
22#include "qgsauthconfigedit.h"
23#include "qgsauthguiutils.h"
24#include "qgsauthmanager.h"
26#include "qgslogger.h"
27
28#include <QHash>
29#include <QMessageBox>
30#include <QRegularExpression>
31#include <QString>
32#include <QTimer>
33
34#include "moc_qgsauthconfigselect.cpp"
35
36using namespace Qt::StringLiterals;
37
38QgsAuthConfigSelect::QgsAuthConfigSelect( QWidget *parent, const QString &dataprovider )
39 : QWidget( parent )
40 , mDataProvider( dataprovider )
41{
42 if ( QgsApplication::authManager()->isDisabled() )
43 {
44 mDisabled = true;
45 mAuthNotifyLayout = new QVBoxLayout;
46 this->setLayout( mAuthNotifyLayout );
47 mAuthNotify = new QLabel( QgsApplication::authManager()->disabledMessage(), this );
48 mAuthNotifyLayout->addWidget( mAuthNotify );
49 }
50 else
51 {
52 setupUi( this );
53 connect( cmbConfigSelect, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsAuthConfigSelect::cmbConfigSelect_currentIndexChanged );
54 connect( btnConfigAdd, &QToolButton::clicked, this, &QgsAuthConfigSelect::btnConfigAdd_clicked );
55 connect( btnConfigEdit, &QToolButton::clicked, this, &QgsAuthConfigSelect::btnConfigEdit_clicked );
56 connect( btnConfigRemove, &QToolButton::clicked, this, &QgsAuthConfigSelect::btnConfigRemove_clicked );
57 connect( btnConfigMsgClear, &QToolButton::clicked, this, &QgsAuthConfigSelect::btnConfigMsgClear_clicked );
58
59 // Set icons and remove texts
60 btnConfigAdd->setIcon( QgsApplication::getThemeIcon( u"/symbologyAdd.svg"_s ) );
61 btnConfigRemove->setIcon( QgsApplication::getThemeIcon( u"/symbologyRemove.svg"_s ) );
62 btnConfigEdit->setIcon( QgsApplication::getThemeIcon( u"/mActionToggleEditing.svg"_s ) );
63 btnConfigMsgClear->setIcon( QgsApplication::getThemeIcon( u"/mIconClose.svg"_s ) );
64
65 btnConfigAdd->setText( QString() );
66 btnConfigRemove->setText( QString() );
67 btnConfigEdit->setText( QString() );
68 btnConfigMsgClear->setText( QString() );
69
70 leConfigMsg->setStyleSheet( u"QLineEdit{background-color: %1}"_s.arg( QgsAuthGuiUtils::yellowColor().name() ) );
71
72 clearConfig();
74 populateConfigSelector();
75 }
76}
77
78void QgsAuthConfigSelect::setConfigId( const QString &authcfg )
79{
80 if ( mDisabled && mAuthNotify )
81 {
82 mAuthNotify->setText( QgsApplication::authManager()->disabledMessage() + "\n\n" + tr( "Authentication config id not loaded: %1" ).arg( authcfg ) );
83 }
84 else
85 {
86 if ( mAuthCfg != authcfg )
87 {
88 mAuthCfg = authcfg;
89 }
90 // avoid duplicate call to loadConfig(), which may potentially be triggered by combo box index changes in the
91 // call to populateConfigSelector(). We *always* call loadConfig() after this, so we don't want to do it twice.
92 mTemporarilyBlockLoad = true;
93 populateConfigSelector();
94 mTemporarilyBlockLoad = false;
95 loadConfig();
96 }
97}
98
100{
101 if ( mDisabled )
102 {
103 return;
104 }
105
106 mDataProvider = key;
107 populateConfigSelector();
108}
109
110void QgsAuthConfigSelect::loadConfig()
111{
112 clearConfig();
113 if ( !mAuthCfg.isEmpty() && mConfigs.contains( mAuthCfg ) )
114 {
115 const QgsAuthMethodConfig config = mConfigs.value( mAuthCfg );
116 const QString authMethodKey = QgsApplication::authManager()->configAuthMethodKey( mAuthCfg );
117 QString methoddesc = tr( "Missing authentication method description" );
119 if ( meta )
120 {
121 methoddesc = meta->description();
122 }
123 cmbConfigSelect->setToolTip( tr(
124 "<ul><li><b>Method type:</b> %1</li>"
125 "<li><b>Configuration ID:</b> %2</li></ul>"
126 )
127 .arg( methoddesc, config.id() ) );
128 btnConfigEdit->setEnabled( true );
129 btnConfigRemove->setEnabled( true );
130 }
131 emit selectedConfigIdChanged( mAuthCfg );
132}
133
134void QgsAuthConfigSelect::clearConfig()
135{
136 cmbConfigSelect->setToolTip( QString() );
137 btnConfigEdit->setEnabled( false );
138 btnConfigRemove->setEnabled( false );
139}
140
141void QgsAuthConfigSelect::validateConfig()
142{
143 if ( !mAuthCfg.isEmpty() && !mConfigs.contains( mAuthCfg ) )
144 {
145 showMessage( tr( "Configuration '%1' not in database" ).arg( mAuthCfg ) );
146 mAuthCfg.clear();
147 }
148}
149
150void QgsAuthConfigSelect::populateConfigSelector()
151{
152 loadAvailableConfigs();
153 validateConfig();
154
155 cmbConfigSelect->blockSignals( true );
156 cmbConfigSelect->clear();
157 cmbConfigSelect->addItem( tr( "No Authentication" ), "0" );
158
159 QgsStringMap sortmap;
160 QgsAuthMethodConfigsMap::const_iterator cit = mConfigs.constBegin();
161 for ( cit = mConfigs.constBegin(); cit != mConfigs.constEnd(); ++cit )
162 {
163 const QgsAuthMethodConfig config = cit.value();
164 sortmap.insert( u"%1 (%2)"_s.arg( config.name(), config.method() ), cit.key() );
165 }
166
167 QgsStringMap::const_iterator sm = sortmap.constBegin();
168 for ( sm = sortmap.constBegin(); sm != sortmap.constEnd(); ++sm )
169 {
170 cmbConfigSelect->addItem( sm.key(), sm.value() );
171 }
172 cmbConfigSelect->blockSignals( false );
173
174 int indx = 0;
175 if ( !mAuthCfg.isEmpty() )
176 {
177 indx = cmbConfigSelect->findData( mAuthCfg );
178 }
179 cmbConfigSelect->setCurrentIndex( indx > 0 ? indx : 0 );
180}
181
182void QgsAuthConfigSelect::showMessage( const QString &msg )
183{
184 if ( mDisabled )
185 {
186 return;
187 }
188 leConfigMsg->setText( msg );
189 frConfigMsg->setVisible( true );
190}
191
193{
194 if ( mDisabled )
195 {
196 return;
197 }
198 leConfigMsg->clear();
199 frConfigMsg->setVisible( false );
200}
201
202void QgsAuthConfigSelect::loadAvailableConfigs()
203{
204 mConfigs.clear();
205 mConfigs = QgsApplication::authManager()->availableAuthMethodConfigs( mDataProvider );
206}
207
208void QgsAuthConfigSelect::cmbConfigSelect_currentIndexChanged( int index )
209{
210 const QString authcfg = cmbConfigSelect->itemData( index ).toString();
211 mAuthCfg = ( !authcfg.isEmpty() && authcfg != "0"_L1 ) ? authcfg : QString();
212 if ( !mTemporarilyBlockLoad )
213 loadConfig();
214}
215
216void QgsAuthConfigSelect::btnConfigAdd_clicked()
217{
218 if ( !QgsApplication::authManager()->setMasterPassword( true ) )
219 return;
220
221 QgsAuthConfigEdit *ace = new QgsAuthConfigEdit( this, QString(), mDataProvider );
222 ace->setWindowModality( Qt::WindowModal );
223 if ( ace->exec() )
224 {
225 setConfigId( ace->configId() );
226 }
227 ace->deleteLater();
228}
229
230void QgsAuthConfigSelect::btnConfigEdit_clicked()
231{
232 if ( !QgsApplication::authManager()->setMasterPassword( true ) )
233 return;
234
235 QgsAuthConfigEdit *ace = new QgsAuthConfigEdit( this, mAuthCfg, mDataProvider );
236 ace->setWindowModality( Qt::WindowModal );
237 if ( ace->exec() )
238 {
239 //qDebug( "Edit returned config Id: %s", ace->configId().toLatin1().constData() );
240 setConfigId( ace->configId() );
241 }
242 ace->deleteLater();
243}
244
245void QgsAuthConfigSelect::btnConfigRemove_clicked()
246{
247 if ( QMessageBox::warning(
248 this,
249 tr( "Remove Authentication" ),
250 tr(
251 "Are you sure that you want to permanently remove this configuration right now?\n\n"
252 "Operation can NOT be undone!"
253 ),
254 QMessageBox::Ok | QMessageBox::Cancel,
255 QMessageBox::Cancel
256 )
257 == QMessageBox::Cancel )
258 {
259 return;
260 }
261
262 if ( QgsApplication::authManager()->removeAuthenticationConfig( mAuthCfg ) )
263 {
264 emit selectedConfigIdRemoved( mAuthCfg );
265 setConfigId( QString() );
266 }
267}
268
269void QgsAuthConfigSelect::btnConfigMsgClear_clicked()
270{
271 clearMessage();
272}
273
274
276
277#include <QPushButton>
278
279QgsAuthConfigUriEdit::QgsAuthConfigUriEdit( QWidget *parent, const QString &datauri, const QString &dataprovider )
280 : QDialog( parent )
281{
282 if ( QgsApplication::authManager()->isDisabled() )
283 {
284 mDisabled = true;
285 mAuthNotifyLayout = new QVBoxLayout;
286 this->setLayout( mAuthNotifyLayout );
287 mAuthNotify = new QLabel( QgsApplication::authManager()->disabledMessage(), this );
288 mAuthNotifyLayout->addWidget( mAuthNotify );
289 }
290 else
291 {
292 setupUi( this );
293
294 setWindowTitle( tr( "Authentication Config ID String Editor" ) );
295
296 buttonBox->button( QDialogButtonBox::Close )->setDefault( true );
297 connect( buttonBox, &QDialogButtonBox::rejected, this, &QWidget::close );
298 connect( buttonBox, &QDialogButtonBox::accepted, this, &QgsAuthConfigUriEdit::saveChanges );
299
300 connect( buttonBox->button( QDialogButtonBox::Reset ), &QAbstractButton::clicked, this, &QgsAuthConfigUriEdit::resetChanges );
301
302 connect( wdgtAuthSelect, &QgsAuthConfigSelect::selectedConfigIdChanged, this, &QgsAuthConfigUriEdit::authCfgUpdated );
303 connect( wdgtAuthSelect, &QgsAuthConfigSelect::selectedConfigIdRemoved, this, &QgsAuthConfigUriEdit::authCfgRemoved );
304
305 wdgtAuthSelect->setDataProviderKey( dataprovider );
306 setDataSourceUri( datauri );
307 }
308}
309
310void QgsAuthConfigUriEdit::setDataSourceUri( const QString &datauri )
311{
312 if ( mDisabled )
313 {
314 return;
315 }
316 if ( datauri.isEmpty() )
317 return;
318
319 mDataUri = mDataUriOrig = datauri;
320
321 teDataUri->setPlainText( mDataUri );
322
323 if ( authCfgIndex() == -1 )
324 {
325 wdgtAuthSelect->showMessage( tr( "No authcfg in Data Source URI" ) );
326 return;
327 }
328
329 selectAuthCfgInUri();
330
331 mAuthCfg = authCfgFromUri();
332
333 QgsDebugMsgLevel( u"Parsed authcfg ID: %1"_s.arg( mAuthCfg ), 2 );
334
335 wdgtAuthSelect->blockSignals( true );
336 wdgtAuthSelect->setConfigId( mAuthCfg );
337 wdgtAuthSelect->blockSignals( false );
338}
339
341{
342 if ( mDisabled )
343 {
344 return QString();
345 }
346 return mDataUri;
347}
348
349bool QgsAuthConfigUriEdit::hasConfigId( const QString &txt )
350{
351 if ( QgsApplication::authManager()->isDisabled() )
352 {
353 return false;
354 }
356}
357
358void QgsAuthConfigUriEdit::saveChanges()
359{
360 this->accept();
361}
362
363void QgsAuthConfigUriEdit::resetChanges()
364{
365 wdgtAuthSelect->clearMessage();
366 setDataSourceUri( mDataUriOrig );
367}
368
369void QgsAuthConfigUriEdit::authCfgUpdated( const QString &authcfg )
370{
371 mAuthCfg = authcfg;
372
373 if ( mAuthCfg.size() != 7 )
374 {
375 mAuthCfg.clear();
376 removeAuthCfgFromUri();
377 }
378 else
379 {
380 updateUriWithAuthCfg();
381 }
382 teDataUri->clear();
383 teDataUri->setPlainText( mDataUri );
384 selectAuthCfgInUri();
385}
386
387void QgsAuthConfigUriEdit::authCfgRemoved( const QString &authcfg )
388{
389 if ( authCfgFromUri() == authcfg )
390 {
391 removeAuthCfgFromUri();
392 }
393}
394
395int QgsAuthConfigUriEdit::authCfgIndex()
396{
397 return mDataUri.indexOf( QRegularExpression( QgsApplication::authManager()->configIdRegex() ) );
398}
399
400QString QgsAuthConfigUriEdit::authCfgFromUri()
401{
402 const int startindex = authCfgIndex();
403 if ( startindex == -1 )
404 return QString();
405
406 return mDataUri.mid( startindex + 8, 7 );
407}
408
409void QgsAuthConfigUriEdit::selectAuthCfgInUri()
410{
411 const int startindex = authCfgIndex();
412 if ( startindex == -1 )
413 return;
414
415 // authcfg=.{7} will always be 15 chars
416 QTextCursor tc = teDataUri->textCursor();
417 tc.setPosition( startindex );
418 tc.setPosition( startindex + 15, QTextCursor::KeepAnchor );
419 teDataUri->setTextCursor( tc );
420 teDataUri->setFocus();
421}
422
423void QgsAuthConfigUriEdit::updateUriWithAuthCfg()
424{
425 const int startindex = authCfgIndex();
426 if ( startindex == -1 )
427 {
428 if ( mAuthCfg.size() == 7 )
429 {
430 wdgtAuthSelect->showMessage( tr( "Adding authcfg to URI not supported" ) );
431 }
432 return;
433 }
434
435 mDataUri = mDataUri.replace( startindex + 8, 7, mAuthCfg );
436}
437
438void QgsAuthConfigUriEdit::removeAuthCfgFromUri()
439{
440 int startindex = authCfgIndex();
441 if ( startindex == -1 )
442 return;
443
444 // add any preceding space so two spaces will not result after removal
445 int rmvlen = 15;
446 if ( startindex - 1 >= 0 && ( mDataUri.at( startindex - 1 ).isSpace() || mDataUri.at( startindex - 1 ) == QChar( '&' ) ) )
447 {
448 startindex -= 1;
449 rmvlen += 1;
450 }
451
452 // trim any leftover spaces or & from ends
453 mDataUri = mDataUri.remove( startindex, rmvlen ).trimmed();
454 if ( mDataUri.at( 0 ) == QChar( '&' ) )
455 mDataUri = mDataUri.remove( 0, 1 );
456
457 // trim any & from
458
459 mAuthCfg.clear();
460}
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QgsAuthManager * authManager()
Returns the application's authentication manager instance.
const QString configId() const
Authentication config id, updated with generated id when a new config is saved to auth database.
void clearMessage()
Clear and hide small message bar.
void setConfigId(const QString &authcfg)
Sets the authentication config id for the resource.
void selectedConfigIdRemoved(const QString &authcfg)
Emitted when authentication config is removed.
QgsAuthConfigSelect(QWidget *parent=nullptr, const QString &dataprovider=QString())
Create a dialog for setting an associated authentication config, either from existing configs,...
void selectedConfigIdChanged(const QString &authcfg)
Emitted when authentication config is changed or missing.
void setDataProviderKey(const QString &key)
Sets key of layer provider, if applicable.
void showMessage(const QString &msg)
Show a small message bar with a close button.
void setDataSourceUri(const QString &datauri)
Sets the data source URI to parse.
static bool hasConfigId(const QString &txt)
Whether a string contains an authcfg ID.
QString dataSourceUri()
The returned, possibly edited data source URI.
QgsAuthConfigUriEdit(QWidget *parent=nullptr, const QString &datauri=QString(), const QString &dataprovider=QString())
Construct wrapper dialog for select widget to edit an authcfg in a data source URI.
static QColor yellowColor()
Yellow color representing caution regarding action.
static bool hasConfigId(const QString &txt)
Returns whether a string includes an authcfg ID token.
const QgsAuthMethodMetadata * authMethodMetadata(const QString &authMethodKey)
Gets authentication method metadata via its key.
QgsAuthMethodConfigsMap availableAuthMethodConfigs(const QString &dataprovider=QString())
Gets mapping of authentication config ids and their base configs (not decrypted data).
QString configAuthMethodKey(const QString &authcfg) const
Gets key of authentication method associated with config ID.
Configuration storage class for authentication method configurations.
QString method() const
Textual key of the associated authentication method.
const QString name() const
Gets name of configuration.
const QString id() const
Gets 'authcfg' 7-character alphanumeric ID of the config.
Holds data auth method key, description, and associated shared library file information.
QString description() const
Returns descriptive text for the method.
QMap< QString, QString > QgsStringMap
Definition qgis.h:7475
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:63