QGIS API Documentation 3.39.0-Master (47f7b3a4989)
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 "ui_qgsauthconfigselect.h"
19
20#include "qgsauthconfig.h"
21#include "qgsauthguiutils.h"
22#include "qgsauthmanager.h"
23#include "qgsauthconfigedit.h"
24#include "qgslogger.h"
25#include "qgsapplication.h"
27
28#include <QHash>
29#include <QMessageBox>
30#include <QTimer>
31#include <QRegularExpression>
32
33
34QgsAuthConfigSelect::QgsAuthConfigSelect( QWidget *parent, const QString &dataprovider )
35 : QWidget( parent )
36 , mDataProvider( dataprovider )
37{
38 if ( QgsApplication::authManager()->isDisabled() )
39 {
40 mDisabled = true;
41 mAuthNotifyLayout = new QVBoxLayout;
42 this->setLayout( mAuthNotifyLayout );
43 mAuthNotify = new QLabel( QgsApplication::authManager()->disabledMessage(), this );
44 mAuthNotifyLayout->addWidget( mAuthNotify );
45 }
46 else
47 {
48 setupUi( this );
49 connect( cmbConfigSelect, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsAuthConfigSelect::cmbConfigSelect_currentIndexChanged );
50 connect( btnConfigAdd, &QToolButton::clicked, this, &QgsAuthConfigSelect::btnConfigAdd_clicked );
51 connect( btnConfigEdit, &QToolButton::clicked, this, &QgsAuthConfigSelect::btnConfigEdit_clicked );
52 connect( btnConfigRemove, &QToolButton::clicked, this, &QgsAuthConfigSelect::btnConfigRemove_clicked );
53 connect( btnConfigMsgClear, &QToolButton::clicked, this, &QgsAuthConfigSelect::btnConfigMsgClear_clicked );
54
55 // Set icons and remove texts
56 btnConfigAdd->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/symbologyAdd.svg" ) ) );
57 btnConfigRemove->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/symbologyRemove.svg" ) ) );
58 btnConfigEdit->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionToggleEditing.svg" ) ) );
59 btnConfigMsgClear->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mIconClose.svg" ) ) );
60
61 btnConfigAdd->setText( QString() );
62 btnConfigRemove->setText( QString() );
63 btnConfigEdit->setText( QString() );
64 btnConfigMsgClear->setText( QString() );
65
66 leConfigMsg->setStyleSheet( QStringLiteral( "QLineEdit{background-color: %1}" )
67 .arg( QgsAuthGuiUtils::yellowColor().name() ) );
68
69 clearConfig();
71 populateConfigSelector();
72 }
73}
74
75void QgsAuthConfigSelect::setConfigId( const QString &authcfg )
76{
77 if ( mDisabled && mAuthNotify )
78 {
79 mAuthNotify->setText( QgsApplication::authManager()->disabledMessage() + "\n\n" +
80 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>" ).arg( methoddesc, config.id( ) ) );
123 btnConfigEdit->setEnabled( true );
124 btnConfigRemove->setEnabled( true );
125 }
126 emit selectedConfigIdChanged( mAuthCfg );
127}
128
129void QgsAuthConfigSelect::clearConfig()
130{
131 cmbConfigSelect->setToolTip( QString() );
132 btnConfigEdit->setEnabled( false );
133 btnConfigRemove->setEnabled( false );
134}
135
136void QgsAuthConfigSelect::validateConfig()
137{
138 if ( !mAuthCfg.isEmpty() && !mConfigs.contains( mAuthCfg ) )
139 {
140 showMessage( tr( "Configuration '%1' not in database" ).arg( mAuthCfg ) );
141 mAuthCfg.clear();
142 }
143}
144
145void QgsAuthConfigSelect::populateConfigSelector()
146{
147 loadAvailableConfigs();
148 validateConfig();
149
150 cmbConfigSelect->blockSignals( true );
151 cmbConfigSelect->clear();
152 cmbConfigSelect->addItem( tr( "No Authentication" ), "0" );
153
154 QgsStringMap sortmap;
155 QgsAuthMethodConfigsMap::const_iterator cit = mConfigs.constBegin();
156 for ( cit = mConfigs.constBegin(); cit != mConfigs.constEnd(); ++cit )
157 {
158 const QgsAuthMethodConfig config = cit.value();
159 sortmap.insert( QStringLiteral( "%1 (%2)" ).arg( config.name(), config.method() ), cit.key() );
160 }
161
162 QgsStringMap::const_iterator sm = sortmap.constBegin();
163 for ( sm = sortmap.constBegin(); sm != sortmap.constEnd(); ++sm )
164 {
165 cmbConfigSelect->addItem( sm.key(), sm.value() );
166 }
167 cmbConfigSelect->blockSignals( false );
168
169 int indx = 0;
170 if ( !mAuthCfg.isEmpty() )
171 {
172 indx = cmbConfigSelect->findData( mAuthCfg );
173 }
174 cmbConfigSelect->setCurrentIndex( indx > 0 ? indx : 0 );
175}
176
177void QgsAuthConfigSelect::showMessage( const QString &msg )
178{
179 if ( mDisabled )
180 {
181 return;
182 }
183 leConfigMsg->setText( msg );
184 frConfigMsg->setVisible( true );
185}
186
188{
189 if ( mDisabled )
190 {
191 return;
192 }
193 leConfigMsg->clear();
194 frConfigMsg->setVisible( false );
195}
196
197void QgsAuthConfigSelect::loadAvailableConfigs()
198{
199 mConfigs.clear();
200 mConfigs = QgsApplication::authManager()->availableAuthMethodConfigs( mDataProvider );
201}
202
203void QgsAuthConfigSelect::cmbConfigSelect_currentIndexChanged( int index )
204{
205 const QString authcfg = cmbConfigSelect->itemData( index ).toString();
206 mAuthCfg = ( !authcfg.isEmpty() && authcfg != QLatin1String( "0" ) ) ? authcfg : QString();
207 if ( !mTemporarilyBlockLoad )
208 loadConfig();
209}
210
211void QgsAuthConfigSelect::btnConfigAdd_clicked()
212{
213 if ( !QgsApplication::authManager()->setMasterPassword( true ) )
214 return;
215
216 QgsAuthConfigEdit *ace = new QgsAuthConfigEdit( this, QString(), mDataProvider );
217 ace->setWindowModality( Qt::WindowModal );
218 if ( ace->exec() )
219 {
220 setConfigId( ace->configId() );
221 }
222 ace->deleteLater();
223}
224
225void QgsAuthConfigSelect::btnConfigEdit_clicked()
226{
227 if ( !QgsApplication::authManager()->setMasterPassword( true ) )
228 return;
229
230 QgsAuthConfigEdit *ace = new QgsAuthConfigEdit( this, mAuthCfg, mDataProvider );
231 ace->setWindowModality( Qt::WindowModal );
232 if ( ace->exec() )
233 {
234 //qDebug( "Edit returned config Id: %s", ace->configId().toLatin1().constData() );
235 setConfigId( ace->configId() );
236 }
237 ace->deleteLater();
238}
239
240void QgsAuthConfigSelect::btnConfigRemove_clicked()
241{
242 if ( QMessageBox::warning( this, tr( "Remove Authentication" ),
243 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,
246 QMessageBox::Cancel ) == 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()
437 || mDataUri.at( startindex - 1 ) == QChar( '&' ) ) )
438 {
439 startindex -= 1;
440 rmvlen += 1;
441 }
442
443 // trim any leftover spaces or & from ends
444 mDataUri = mDataUri.remove( startindex, rmvlen ).trimmed();
445 if ( mDataUri.at( 0 ) == QChar( '&' ) )
446 mDataUri = mDataUri.remove( 0, 1 );
447
448 // trim any & from
449
450 mAuthCfg.clear();
451}
452
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:6003
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:39