QGIS API Documentation 3.41.0-Master (57ec4277f5e)
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" + tr( "Authentication config id not loaded: %1" ).arg( authcfg ) );
81 }
82 else
83 {
84 if ( mAuthCfg != authcfg )
85 {
86 mAuthCfg = authcfg;
87 }
88 // avoid duplicate call to loadConfig(), which may potentially be triggered by combo box index changes in the
89 // call to populateConfigSelector(). We *always* call loadConfig() after this, so we don't want to do it twice.
90 mTemporarilyBlockLoad = true;
91 populateConfigSelector();
92 mTemporarilyBlockLoad = false;
93 loadConfig();
94 }
95}
96
98{
99 if ( mDisabled )
100 {
101 return;
102 }
103
104 mDataProvider = key;
105 populateConfigSelector();
106}
107
108void QgsAuthConfigSelect::loadConfig()
109{
110 clearConfig();
111 if ( !mAuthCfg.isEmpty() && mConfigs.contains( mAuthCfg ) )
112 {
113 const QgsAuthMethodConfig config = mConfigs.value( mAuthCfg );
114 const QString authMethodKey = QgsApplication::authManager()->configAuthMethodKey( mAuthCfg );
115 QString methoddesc = tr( "Missing authentication method description" );
117 if ( meta )
118 {
119 methoddesc = meta->description();
120 }
121 cmbConfigSelect->setToolTip( tr( "<ul><li><b>Method type:</b> %1</li>"
122 "<li><b>Configuration ID:</b> %2</li></ul>" )
123 .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" ), tr( "Are you sure that you want to permanently remove this configuration right now?\n\n"
244 "Operation can NOT be undone!" ),
245 QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel )
246 == QMessageBox::Cancel )
247 {
248 return;
249 }
250
251 if ( QgsApplication::authManager()->removeAuthenticationConfig( mAuthCfg ) )
252 {
253 emit selectedConfigIdRemoved( mAuthCfg );
254 setConfigId( QString() );
255 }
256}
257
258void QgsAuthConfigSelect::btnConfigMsgClear_clicked()
259{
260 clearMessage();
261}
262
263
265
266#include <QPushButton>
267
268QgsAuthConfigUriEdit::QgsAuthConfigUriEdit( QWidget *parent, const QString &datauri, const QString &dataprovider )
269 : QDialog( parent )
270{
271 if ( QgsApplication::authManager()->isDisabled() )
272 {
273 mDisabled = true;
274 mAuthNotifyLayout = new QVBoxLayout;
275 this->setLayout( mAuthNotifyLayout );
276 mAuthNotify = new QLabel( QgsApplication::authManager()->disabledMessage(), this );
277 mAuthNotifyLayout->addWidget( mAuthNotify );
278 }
279 else
280 {
281 setupUi( this );
282
283 setWindowTitle( tr( "Authentication Config ID String Editor" ) );
284
285 buttonBox->button( QDialogButtonBox::Close )->setDefault( true );
286 connect( buttonBox, &QDialogButtonBox::rejected, this, &QWidget::close );
287 connect( buttonBox, &QDialogButtonBox::accepted, this, &QgsAuthConfigUriEdit::saveChanges );
288
289 connect( buttonBox->button( QDialogButtonBox::Reset ), &QAbstractButton::clicked, this, &QgsAuthConfigUriEdit::resetChanges );
290
291 connect( wdgtAuthSelect, &QgsAuthConfigSelect::selectedConfigIdChanged, this, &QgsAuthConfigUriEdit::authCfgUpdated );
292 connect( wdgtAuthSelect, &QgsAuthConfigSelect::selectedConfigIdRemoved, this, &QgsAuthConfigUriEdit::authCfgRemoved );
293
294 wdgtAuthSelect->setDataProviderKey( dataprovider );
295 setDataSourceUri( datauri );
296 }
297}
298
299void QgsAuthConfigUriEdit::setDataSourceUri( const QString &datauri )
300{
301 if ( mDisabled )
302 {
303 return;
304 }
305 if ( datauri.isEmpty() )
306 return;
307
308 mDataUri = mDataUriOrig = datauri;
309
310 teDataUri->setPlainText( mDataUri );
311
312 if ( authCfgIndex() == -1 )
313 {
314 wdgtAuthSelect->showMessage( tr( "No authcfg in Data Source URI" ) );
315 return;
316 }
317
318 selectAuthCfgInUri();
319
320 mAuthCfg = authCfgFromUri();
321
322 QgsDebugMsgLevel( QStringLiteral( "Parsed authcfg ID: %1" ).arg( mAuthCfg ), 2 );
323
324 wdgtAuthSelect->blockSignals( true );
325 wdgtAuthSelect->setConfigId( mAuthCfg );
326 wdgtAuthSelect->blockSignals( false );
327}
328
330{
331 if ( mDisabled )
332 {
333 return QString();
334 }
335 return mDataUri;
336}
337
338bool QgsAuthConfigUriEdit::hasConfigId( const QString &txt )
339{
340 if ( QgsApplication::authManager()->isDisabled() )
341 {
342 return false;
343 }
345}
346
347void QgsAuthConfigUriEdit::saveChanges()
348{
349 this->accept();
350}
351
352void QgsAuthConfigUriEdit::resetChanges()
353{
354 wdgtAuthSelect->clearMessage();
355 setDataSourceUri( mDataUriOrig );
356}
357
358void QgsAuthConfigUriEdit::authCfgUpdated( const QString &authcfg )
359{
360 mAuthCfg = authcfg;
361
362 if ( mAuthCfg.size() != 7 )
363 {
364 mAuthCfg.clear();
365 removeAuthCfgFromUri();
366 }
367 else
368 {
369 updateUriWithAuthCfg();
370 }
371 teDataUri->clear();
372 teDataUri->setPlainText( mDataUri );
373 selectAuthCfgInUri();
374}
375
376void QgsAuthConfigUriEdit::authCfgRemoved( const QString &authcfg )
377{
378 if ( authCfgFromUri() == authcfg )
379 {
380 removeAuthCfgFromUri();
381 }
382}
383
384int QgsAuthConfigUriEdit::authCfgIndex()
385{
386 return mDataUri.indexOf( QRegularExpression( QgsApplication::authManager()->configIdRegex() ) );
387}
388
389QString QgsAuthConfigUriEdit::authCfgFromUri()
390{
391 const int startindex = authCfgIndex();
392 if ( startindex == -1 )
393 return QString();
394
395 return mDataUri.mid( startindex + 8, 7 );
396}
397
398void QgsAuthConfigUriEdit::selectAuthCfgInUri()
399{
400 const int startindex = authCfgIndex();
401 if ( startindex == -1 )
402 return;
403
404 // authcfg=.{7} will always be 15 chars
405 QTextCursor tc = teDataUri->textCursor();
406 tc.setPosition( startindex );
407 tc.setPosition( startindex + 15, QTextCursor::KeepAnchor );
408 teDataUri->setTextCursor( tc );
409 teDataUri->setFocus();
410}
411
412void QgsAuthConfigUriEdit::updateUriWithAuthCfg()
413{
414 const int startindex = authCfgIndex();
415 if ( startindex == -1 )
416 {
417 if ( mAuthCfg.size() == 7 )
418 {
419 wdgtAuthSelect->showMessage( tr( "Adding authcfg to URI not supported" ) );
420 }
421 return;
422 }
423
424 mDataUri = mDataUri.replace( startindex + 8, 7, mAuthCfg );
425}
426
427void QgsAuthConfigUriEdit::removeAuthCfgFromUri()
428{
429 int startindex = authCfgIndex();
430 if ( startindex == -1 )
431 return;
432
433 // add any preceding space so two spaces will not result after removal
434 int rmvlen = 15;
435 if ( startindex - 1 >= 0
436 && ( mDataUri.at( startindex - 1 ).isSpace() || mDataUri.at( startindex - 1 ) == QChar( '&' ) ) )
437 {
438 startindex -= 1;
439 rmvlen += 1;
440 }
441
442 // trim any leftover spaces or & from ends
443 mDataUri = mDataUri.remove( startindex, rmvlen ).trimmed();
444 if ( mDataUri.at( 0 ) == QChar( '&' ) )
445 mDataUri = mDataUri.remove( 0, 1 );
446
447 // trim any & from
448
449 mAuthCfg.clear();
450}
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:6604
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:39