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