QGIS API Documentation 3.99.0-Master (357b655ed83)
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
71 .arg( QgsAuthGuiUtils::yellowColor().name() ) );
72
73 clearConfig();
75 populateConfigSelector();
76 }
77}
78
79void QgsAuthConfigSelect::setConfigId( const QString &authcfg )
80{
81 if ( mDisabled && mAuthNotify )
82 {
83 mAuthNotify->setText( QgsApplication::authManager()->disabledMessage() + "\n\n" + tr( "Authentication config id not loaded: %1" ).arg( authcfg ) );
84 }
85 else
86 {
87 if ( mAuthCfg != authcfg )
88 {
89 mAuthCfg = authcfg;
90 }
91 // avoid duplicate call to loadConfig(), which may potentially be triggered by combo box index changes in the
92 // call to populateConfigSelector(). We *always* call loadConfig() after this, so we don't want to do it twice.
93 mTemporarilyBlockLoad = true;
94 populateConfigSelector();
95 mTemporarilyBlockLoad = false;
96 loadConfig();
97 }
98}
99
101{
102 if ( mDisabled )
103 {
104 return;
105 }
106
107 mDataProvider = key;
108 populateConfigSelector();
109}
110
111void QgsAuthConfigSelect::loadConfig()
112{
113 clearConfig();
114 if ( !mAuthCfg.isEmpty() && mConfigs.contains( mAuthCfg ) )
115 {
116 const QgsAuthMethodConfig config = mConfigs.value( mAuthCfg );
117 const QString authMethodKey = QgsApplication::authManager()->configAuthMethodKey( mAuthCfg );
118 QString methoddesc = tr( "Missing authentication method description" );
120 if ( meta )
121 {
122 methoddesc = meta->description();
123 }
124 cmbConfigSelect->setToolTip( tr( "<ul><li><b>Method type:</b> %1</li>"
125 "<li><b>Configuration ID:</b> %2</li></ul>" )
126 .arg( methoddesc, config.id() ) );
127 btnConfigEdit->setEnabled( true );
128 btnConfigRemove->setEnabled( true );
129 }
130 emit selectedConfigIdChanged( mAuthCfg );
131}
132
133void QgsAuthConfigSelect::clearConfig()
134{
135 cmbConfigSelect->setToolTip( QString() );
136 btnConfigEdit->setEnabled( false );
137 btnConfigRemove->setEnabled( false );
138}
139
140void QgsAuthConfigSelect::validateConfig()
141{
142 if ( !mAuthCfg.isEmpty() && !mConfigs.contains( mAuthCfg ) )
143 {
144 showMessage( tr( "Configuration '%1' not in database" ).arg( mAuthCfg ) );
145 mAuthCfg.clear();
146 }
147}
148
149void QgsAuthConfigSelect::populateConfigSelector()
150{
151 loadAvailableConfigs();
152 validateConfig();
153
154 cmbConfigSelect->blockSignals( true );
155 cmbConfigSelect->clear();
156 cmbConfigSelect->addItem( tr( "No Authentication" ), "0" );
157
158 QgsStringMap sortmap;
159 QgsAuthMethodConfigsMap::const_iterator cit = mConfigs.constBegin();
160 for ( cit = mConfigs.constBegin(); cit != mConfigs.constEnd(); ++cit )
161 {
162 const QgsAuthMethodConfig config = cit.value();
163 sortmap.insert( u"%1 (%2)"_s.arg( config.name(), config.method() ), cit.key() );
164 }
165
166 QgsStringMap::const_iterator sm = sortmap.constBegin();
167 for ( sm = sortmap.constBegin(); sm != sortmap.constEnd(); ++sm )
168 {
169 cmbConfigSelect->addItem( sm.key(), sm.value() );
170 }
171 cmbConfigSelect->blockSignals( false );
172
173 int indx = 0;
174 if ( !mAuthCfg.isEmpty() )
175 {
176 indx = cmbConfigSelect->findData( mAuthCfg );
177 }
178 cmbConfigSelect->setCurrentIndex( indx > 0 ? indx : 0 );
179}
180
181void QgsAuthConfigSelect::showMessage( const QString &msg )
182{
183 if ( mDisabled )
184 {
185 return;
186 }
187 leConfigMsg->setText( msg );
188 frConfigMsg->setVisible( true );
189}
190
192{
193 if ( mDisabled )
194 {
195 return;
196 }
197 leConfigMsg->clear();
198 frConfigMsg->setVisible( false );
199}
200
201void QgsAuthConfigSelect::loadAvailableConfigs()
202{
203 mConfigs.clear();
204 mConfigs = QgsApplication::authManager()->availableAuthMethodConfigs( mDataProvider );
205}
206
207void QgsAuthConfigSelect::cmbConfigSelect_currentIndexChanged( int index )
208{
209 const QString authcfg = cmbConfigSelect->itemData( index ).toString();
210 mAuthCfg = ( !authcfg.isEmpty() && authcfg != "0"_L1 ) ? authcfg : QString();
211 if ( !mTemporarilyBlockLoad )
212 loadConfig();
213}
214
215void QgsAuthConfigSelect::btnConfigAdd_clicked()
216{
217 if ( !QgsApplication::authManager()->setMasterPassword( true ) )
218 return;
219
220 QgsAuthConfigEdit *ace = new QgsAuthConfigEdit( this, QString(), mDataProvider );
221 ace->setWindowModality( Qt::WindowModal );
222 if ( ace->exec() )
223 {
224 setConfigId( ace->configId() );
225 }
226 ace->deleteLater();
227}
228
229void QgsAuthConfigSelect::btnConfigEdit_clicked()
230{
231 if ( !QgsApplication::authManager()->setMasterPassword( true ) )
232 return;
233
234 QgsAuthConfigEdit *ace = new QgsAuthConfigEdit( this, mAuthCfg, mDataProvider );
235 ace->setWindowModality( Qt::WindowModal );
236 if ( ace->exec() )
237 {
238 //qDebug( "Edit returned config Id: %s", ace->configId().toLatin1().constData() );
239 setConfigId( ace->configId() );
240 }
241 ace->deleteLater();
242}
243
244void QgsAuthConfigSelect::btnConfigRemove_clicked()
245{
246 if ( QMessageBox::warning( this, tr( "Remove Authentication" ), tr( "Are you sure that you want to permanently remove this configuration right now?\n\n"
247 "Operation can NOT be undone!" ),
248 QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel )
249 == QMessageBox::Cancel )
250 {
251 return;
252 }
253
254 if ( QgsApplication::authManager()->removeAuthenticationConfig( mAuthCfg ) )
255 {
256 emit selectedConfigIdRemoved( mAuthCfg );
257 setConfigId( QString() );
258 }
259}
260
261void QgsAuthConfigSelect::btnConfigMsgClear_clicked()
262{
263 clearMessage();
264}
265
266
268
269#include <QPushButton>
270
271QgsAuthConfigUriEdit::QgsAuthConfigUriEdit( QWidget *parent, const QString &datauri, const QString &dataprovider )
272 : QDialog( parent )
273{
274 if ( QgsApplication::authManager()->isDisabled() )
275 {
276 mDisabled = true;
277 mAuthNotifyLayout = new QVBoxLayout;
278 this->setLayout( mAuthNotifyLayout );
279 mAuthNotify = new QLabel( QgsApplication::authManager()->disabledMessage(), this );
280 mAuthNotifyLayout->addWidget( mAuthNotify );
281 }
282 else
283 {
284 setupUi( this );
285
286 setWindowTitle( tr( "Authentication Config ID String Editor" ) );
287
288 buttonBox->button( QDialogButtonBox::Close )->setDefault( true );
289 connect( buttonBox, &QDialogButtonBox::rejected, this, &QWidget::close );
290 connect( buttonBox, &QDialogButtonBox::accepted, this, &QgsAuthConfigUriEdit::saveChanges );
291
292 connect( buttonBox->button( QDialogButtonBox::Reset ), &QAbstractButton::clicked, this, &QgsAuthConfigUriEdit::resetChanges );
293
294 connect( wdgtAuthSelect, &QgsAuthConfigSelect::selectedConfigIdChanged, this, &QgsAuthConfigUriEdit::authCfgUpdated );
295 connect( wdgtAuthSelect, &QgsAuthConfigSelect::selectedConfigIdRemoved, this, &QgsAuthConfigUriEdit::authCfgRemoved );
296
297 wdgtAuthSelect->setDataProviderKey( dataprovider );
298 setDataSourceUri( datauri );
299 }
300}
301
302void QgsAuthConfigUriEdit::setDataSourceUri( const QString &datauri )
303{
304 if ( mDisabled )
305 {
306 return;
307 }
308 if ( datauri.isEmpty() )
309 return;
310
311 mDataUri = mDataUriOrig = datauri;
312
313 teDataUri->setPlainText( mDataUri );
314
315 if ( authCfgIndex() == -1 )
316 {
317 wdgtAuthSelect->showMessage( tr( "No authcfg in Data Source URI" ) );
318 return;
319 }
320
321 selectAuthCfgInUri();
322
323 mAuthCfg = authCfgFromUri();
324
325 QgsDebugMsgLevel( u"Parsed authcfg ID: %1"_s.arg( mAuthCfg ), 2 );
326
327 wdgtAuthSelect->blockSignals( true );
328 wdgtAuthSelect->setConfigId( mAuthCfg );
329 wdgtAuthSelect->blockSignals( false );
330}
331
333{
334 if ( mDisabled )
335 {
336 return QString();
337 }
338 return mDataUri;
339}
340
341bool QgsAuthConfigUriEdit::hasConfigId( const QString &txt )
342{
343 if ( QgsApplication::authManager()->isDisabled() )
344 {
345 return false;
346 }
348}
349
350void QgsAuthConfigUriEdit::saveChanges()
351{
352 this->accept();
353}
354
355void QgsAuthConfigUriEdit::resetChanges()
356{
357 wdgtAuthSelect->clearMessage();
358 setDataSourceUri( mDataUriOrig );
359}
360
361void QgsAuthConfigUriEdit::authCfgUpdated( const QString &authcfg )
362{
363 mAuthCfg = authcfg;
364
365 if ( mAuthCfg.size() != 7 )
366 {
367 mAuthCfg.clear();
368 removeAuthCfgFromUri();
369 }
370 else
371 {
372 updateUriWithAuthCfg();
373 }
374 teDataUri->clear();
375 teDataUri->setPlainText( mDataUri );
376 selectAuthCfgInUri();
377}
378
379void QgsAuthConfigUriEdit::authCfgRemoved( const QString &authcfg )
380{
381 if ( authCfgFromUri() == authcfg )
382 {
383 removeAuthCfgFromUri();
384 }
385}
386
387int QgsAuthConfigUriEdit::authCfgIndex()
388{
389 return mDataUri.indexOf( QRegularExpression( QgsApplication::authManager()->configIdRegex() ) );
390}
391
392QString QgsAuthConfigUriEdit::authCfgFromUri()
393{
394 const int startindex = authCfgIndex();
395 if ( startindex == -1 )
396 return QString();
397
398 return mDataUri.mid( startindex + 8, 7 );
399}
400
401void QgsAuthConfigUriEdit::selectAuthCfgInUri()
402{
403 const int startindex = authCfgIndex();
404 if ( startindex == -1 )
405 return;
406
407 // authcfg=.{7} will always be 15 chars
408 QTextCursor tc = teDataUri->textCursor();
409 tc.setPosition( startindex );
410 tc.setPosition( startindex + 15, QTextCursor::KeepAnchor );
411 teDataUri->setTextCursor( tc );
412 teDataUri->setFocus();
413}
414
415void QgsAuthConfigUriEdit::updateUriWithAuthCfg()
416{
417 const int startindex = authCfgIndex();
418 if ( startindex == -1 )
419 {
420 if ( mAuthCfg.size() == 7 )
421 {
422 wdgtAuthSelect->showMessage( tr( "Adding authcfg to URI not supported" ) );
423 }
424 return;
425 }
426
427 mDataUri = mDataUri.replace( startindex + 8, 7, mAuthCfg );
428}
429
430void QgsAuthConfigUriEdit::removeAuthCfgFromUri()
431{
432 int startindex = authCfgIndex();
433 if ( startindex == -1 )
434 return;
435
436 // add any preceding space so two spaces will not result after removal
437 int rmvlen = 15;
438 if ( startindex - 1 >= 0
439 && ( mDataUri.at( startindex - 1 ).isSpace() || mDataUri.at( startindex - 1 ) == QChar( '&' ) ) )
440 {
441 startindex -= 1;
442 rmvlen += 1;
443 }
444
445 // trim any leftover spaces or & from ends
446 mDataUri = mDataUri.remove( startindex, rmvlen ).trimmed();
447 if ( mDataUri.at( 0 ) == QChar( '&' ) )
448 mDataUri = mDataUri.remove( 0, 1 );
449
450 // trim any & from
451
452 mAuthCfg.clear();
453}
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:7448
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:63