QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgsauthconfigedit.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsauthconfigedit.cpp
3  ---------------------
4  begin : September 1, 2015
5  copyright : (C) 2015 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 "qgsauthconfigedit.h"
18 
19 #include <QPushButton>
20 
21 #include "qgsauthmethodmetadata.h"
22 #include "qgsauthconfig.h"
23 #include "qgsauthconfigidedit.h"
24 #include "qgsauthmanager.h"
25 #include "qgsauthmethodedit.h"
26 #include "qgslogger.h"
27 #include "qgsapplication.h"
28 #include "qgsgui.h"
29 
30 QgsAuthConfigEdit::QgsAuthConfigEdit( QWidget *parent, const QString &authcfg, const QString &dataprovider )
31  : QDialog( parent )
32  , mAuthCfg( authcfg )
33  , mDataProvider( dataprovider )
34 
35 {
36  const bool disabled = QgsApplication::authManager()->isDisabled();
37  bool idok = true;
38 
39  if ( !disabled && !authcfg.isEmpty() )
40  {
41  idok = QgsApplication::authManager()->configIds().contains( authcfg );
42  }
43 
44  if ( disabled || !idok )
45  {
46  mAuthNotifyLayout = new QVBoxLayout;
47  this->setLayout( mAuthNotifyLayout );
48 
49  QString msg( disabled ? QgsApplication::authManager()->disabledMessage() : QString() );
50  if ( !authcfg.isEmpty() )
51  {
52  msg += "\n\n" + tr( "Authentication config id not loaded: %1" ).arg( authcfg );
53  }
54  mAuthNotify = new QLabel( msg, this );
55  mAuthNotifyLayout->addWidget( mAuthNotify );
56 
57  mAuthCfg.clear(); // otherwise will continue to try authenticate (and fail) after save
58  buttonBox->button( QDialogButtonBox::Save )->setEnabled( false );
59  }
60  else
61  {
62  setupUi( this );
63  connect( btnClear, &QToolButton::clicked, this, &QgsAuthConfigEdit::btnClear_clicked );
64  connect( leName, &QLineEdit::textChanged, this, &QgsAuthConfigEdit::leName_textChanged );
65  connect( buttonBox, &QDialogButtonBox::rejected, this, &QWidget::close );
66  connect( buttonBox, &QDialogButtonBox::accepted, this, &QgsAuthConfigEdit::saveConfig );
67  connect( buttonBox->button( QDialogButtonBox::Reset ), &QAbstractButton::clicked, this, &QgsAuthConfigEdit::resetConfig );
68 
69  populateAuthMethods();
70 
71  connect( cmbAuthMethods, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ),
72  stkwAuthMethods, &QStackedWidget::setCurrentIndex );
73  connect( cmbAuthMethods, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ),
74  this, [ = ] { validateAuth(); } );
75 
76  connect( authCfgEdit, &QgsAuthConfigIdEdit::validityChanged, this, &QgsAuthConfigEdit::validateAuth );
77 
78  // needed (if only combobox is ever changed)?
79  // connect( stkwAuthMethods, SIGNAL( currentChanged( int ) ),
80  // cmbAuthMethods, SLOT( setCurrentIndex( int ) ) );
81 
82  // connect( stkwAuthMethods, SIGNAL( currentChanged( int ) ),
83  // this, SLOT( validateAuth() ) );
84 
85  if ( cmbAuthMethods->count() > 0 )
86  {
87  cmbAuthMethods->setCurrentIndex( 0 );
88  stkwAuthMethods->setCurrentIndex( 0 );
89  }
90 
91  loadConfig();
92  validateAuth();
93 
94  leName->setFocus();
95  }
96 
98 }
99 
100 void QgsAuthConfigEdit::populateAuthMethods()
101 {
102  const QStringList authMethodKeys = QgsApplication::authManager()->authMethodsKeys( mDataProvider );
103 
104  // sort by auth method description attribute, then populate
105  QMap<QString, const QgsAuthMethodMetadata *> descmap;
106  const auto constAuthMethodKeys = authMethodKeys;
107  for ( const QString &authMethodKey : constAuthMethodKeys )
108  {
109  const QgsAuthMethodMetadata *meta = QgsApplication::authManager()->authMethodMetadata( authMethodKey );
110  if ( !meta )
111  {
112  QgsDebugMsg( QStringLiteral( "Load auth method instance FAILED for auth method key (%1)" ).arg( authMethodKey ) );
113  continue;
114  }
115  descmap.insert( meta->description(), meta );
116  }
117 
118  QMap<QString, const QgsAuthMethodMetadata *>::iterator it = descmap.begin();
119  for ( it = descmap.begin(); it != descmap.end(); ++it )
120  {
121  QgsAuthMethodEdit *editWidget = qobject_cast<QgsAuthMethodEdit *>(
122  QgsApplication::authManager()->authMethodEditWidget( it.value()->key(), this ) );
123  if ( !editWidget )
124  {
125  QgsDebugMsg( QStringLiteral( "Load auth method edit widget FAILED for auth method key (%1)" ).arg( it.value()->key() ) );
126  continue;
127  }
128  connect( editWidget, &QgsAuthMethodEdit::validityChanged, this, &QgsAuthConfigEdit::validateAuth );
129 
130  cmbAuthMethods->addItem( it.key(), QVariant( it.value()->key() ) );
131  stkwAuthMethods->addWidget( editWidget );
132  }
133 }
134 
135 void QgsAuthConfigEdit::loadConfig()
136 {
137  const bool emptyAuthCfg = mAuthCfg.isEmpty();
138  authCfgEdit->setAllowEmptyId( emptyAuthCfg );
139  if ( emptyAuthCfg )
140  {
141  return;
142  }
143 
144  // edit mode requires master password to have been set and verified against auth db
145  if ( !QgsApplication::authManager()->setMasterPassword( true ) )
146  {
147  mAuthCfg.clear();
148  return;
149  }
150 
151  QgsAuthMethodConfig mconfig;
152  if ( !QgsApplication::authManager()->loadAuthenticationConfig( mAuthCfg, mconfig, true ) )
153  {
154  QgsDebugMsg( QStringLiteral( "Loading FAILED for authcfg: %1" ).arg( mAuthCfg ) );
155  return;
156  }
157 
158  if ( !mconfig.isValid( true ) )
159  {
160  QgsDebugMsg( QStringLiteral( "Loading FAILED for authcfg (%1): invalid config" ).arg( mAuthCfg ) );
161  return;
162  }
163 
164  // load basic info
165  leName->setText( mconfig.name() );
166  leResource->setText( mconfig.uri() );
167  authCfgEdit->setAuthConfigId( mconfig.id() );
168 
169  const QString authMethodKey = QgsApplication::authManager()->configAuthMethodKey( mAuthCfg );
170 
171  QgsDebugMsgLevel( QStringLiteral( "Loading authcfg: %1" ).arg( mAuthCfg ), 2 );
172  QgsDebugMsgLevel( QStringLiteral( "Loading auth method: %1" ).arg( authMethodKey ), 2 );
173 
174  if ( authMethodKey.isEmpty() )
175  {
176  QgsDebugMsg( QStringLiteral( "Loading FAILED for authcfg (%1): no auth method found" ).arg( mAuthCfg ) );
177  return;
178  }
179 
180  if ( mconfig.method() != authMethodKey )
181  {
182  QgsDebugMsg( QStringLiteral( "Loading FAILED for authcfg (%1): auth method and key mismatch" ).arg( mAuthCfg ) );
183  return;
184  }
185 
186  const int indx = authMethodIndex( authMethodKey );
187  if ( indx == -1 )
188  {
189  QgsDebugMsg( QStringLiteral( "Loading FAILED for authcfg (%1): no edit widget loaded for auth method '%2'" )
190  .arg( mAuthCfg, authMethodKey ) );
191  if ( cmbAuthMethods->count() > 0 )
192  {
193  cmbAuthMethods->setCurrentIndex( 0 );
194  stkwAuthMethods->setCurrentIndex( 0 );
195  }
196  return;
197  }
198 
199  cmbAuthMethods->setCurrentIndex( indx );
200  stkwAuthMethods->setCurrentIndex( indx );
201 
202  QgsAuthMethodEdit *editWidget = currentEditWidget();
203  if ( !editWidget )
204  {
205  QgsDebugMsg( QStringLiteral( "Cast to edit widget FAILED for authcfg (%1) and auth method key (%2)" )
206  .arg( mAuthCfg, authMethodKey ) );
207  return;
208  }
209 
210  editWidget->loadConfig( mconfig.configMap() );
211 }
212 
213 void QgsAuthConfigEdit::resetConfig()
214 {
215  clearAll();
216  loadConfig();
217  validateAuth();
218 }
219 
220 void QgsAuthConfigEdit::saveConfig()
221 {
222  if ( !QgsApplication::authManager()->setMasterPassword( true ) )
223  return;
224 
225  const QString authMethodKey = cmbAuthMethods->currentData().toString();
226 
227  QgsAuthMethodEdit *editWidget = currentEditWidget();
228  if ( !editWidget )
229  {
230  QgsDebugMsg( QStringLiteral( "Cast to edit widget FAILED)" ) );
231  return;
232  }
233 
234  QgsAuthMethod *authmethod = QgsApplication::authManager()->authMethod( authMethodKey );
235  if ( !authmethod )
236  {
237  QgsDebugMsg( QStringLiteral( "Save auth config FAILED when loading auth method instance from key (%1)" ).arg( authMethodKey ) );
238  return;
239  }
240 
241  QgsAuthMethodConfig mconfig;
242  mconfig.setName( leName->text() );
243  mconfig.setUri( leResource->text() );
244  mconfig.setMethod( authMethodKey );
245  mconfig.setVersion( authmethod->version() );
246  mconfig.setConfigMap( editWidget->configMap() );
247 
248  if ( !mconfig.isValid() )
249  {
250  QgsDebugMsg( QStringLiteral( "Save auth config FAILED: config invalid" ) );
251  return;
252  }
253 
254  const QString authCfgId( authCfgEdit->configId() );
255  if ( !mAuthCfg.isEmpty() )
256  {
257  if ( authCfgId == mAuthCfg ) // update
258  {
259  mconfig.setId( mAuthCfg );
260  if ( QgsApplication::authManager()->updateAuthenticationConfig( mconfig ) )
261  {
262  emit authenticationConfigUpdated( mAuthCfg );
263  }
264  else
265  {
266  QgsDebugMsg( QStringLiteral( "Updating auth config FAILED for authcfg: %1" ).arg( mAuthCfg ) );
267  }
268  }
269  else // store new with unique ID, then delete previous
270  {
271  mconfig.setId( authCfgId );
272  if ( QgsApplication::authManager()->storeAuthenticationConfig( mconfig ) )
273  {
274  emit authenticationConfigStored( authCfgId );
275  if ( !QgsApplication::authManager()->removeAuthenticationConfig( mAuthCfg ) )
276  {
277  QgsDebugMsg( QStringLiteral( "Removal of older auth config FAILED" ) );
278  }
279  mAuthCfg = authCfgId;
280  }
281  else
282  {
283  QgsDebugMsg( QStringLiteral( "Storing new auth config with user-created unique ID FAILED" ) );
284  }
285  }
286  }
287  else if ( mAuthCfg.isEmpty() )
288  {
289  if ( authCfgId.isEmpty() ) // create new with generated ID
290  {
291  if ( QgsApplication::authManager()->storeAuthenticationConfig( mconfig ) )
292  {
293  mAuthCfg = mconfig.id();
294  emit authenticationConfigStored( mAuthCfg );
295  }
296  else
297  {
298  QgsDebugMsg( QStringLiteral( "Storing new auth config FAILED" ) );
299  }
300  }
301  else // create new with user-created unique ID
302  {
303  mconfig.setId( authCfgId );
304  if ( QgsApplication::authManager()->storeAuthenticationConfig( mconfig ) )
305  {
306  mAuthCfg = authCfgId;
307  emit authenticationConfigStored( mAuthCfg );
308  }
309  else
310  {
311  QgsDebugMsg( QStringLiteral( "Storing new auth config with user-created unique ID FAILED" ) );
312  }
313  }
314  }
315 
316  this->accept();
317 }
318 
319 void QgsAuthConfigEdit::btnClear_clicked()
320 {
321  QgsAuthMethodEdit *editWidget = currentEditWidget();
322  if ( !editWidget )
323  {
324  QgsDebugMsg( QStringLiteral( "Cast to edit widget FAILED)" ) );
325  return;
326  }
327 
328  editWidget->clearConfig();
329 
330  validateAuth();
331 }
332 
333 void QgsAuthConfigEdit::clearAll()
334 {
335  leName->clear();
336  leResource->clear();
337  authCfgEdit->clear();
338 
339  for ( int i = 0; i < stkwAuthMethods->count(); i++ )
340  {
341  QgsAuthMethodEdit *editWidget = qobject_cast<QgsAuthMethodEdit *>( stkwAuthMethods->widget( i ) );
342  if ( editWidget )
343  {
344  editWidget->clearConfig();
345  }
346  }
347 
348  validateAuth();
349 }
350 
351 void QgsAuthConfigEdit::validateAuth()
352 {
353  bool authok = !leName->text().isEmpty();
354 
355  QgsAuthMethodEdit *editWidget = currentEditWidget();
356  if ( !editWidget )
357  {
358  QgsDebugMsg( QStringLiteral( "Cast to edit widget FAILED" ) );
359  }
360  else
361  {
362  authok = authok && editWidget->validateConfig();
363  }
364  authok = authok && authCfgEdit->validate();
365 
366  buttonBox->button( QDialogButtonBox::Save )->setEnabled( authok );
367 }
368 
369 void QgsAuthConfigEdit::leName_textChanged( const QString &txt )
370 {
371  Q_UNUSED( txt )
372  validateAuth();
373 }
374 
375 int QgsAuthConfigEdit::authMethodIndex( const QString &authMethodKey )
376 {
377  return cmbAuthMethods->findData( QVariant( authMethodKey ) );
378 }
379 
380 QgsAuthMethodEdit *QgsAuthConfigEdit::currentEditWidget()
381 {
382  return qobject_cast<QgsAuthMethodEdit *>( stkwAuthMethods->currentWidget() );
383 }
qgsauthconfig.h
QgsAuthMethodMetadata
Holds data auth method key, description, and associated shared library file information.
Definition: qgsauthmethodmetadata.h:43
QgsAuthManager::authMethodsKeys
QStringList authMethodsKeys(const QString &dataprovider=QString())
Gets keys of supported authentication methods.
Definition: qgsauthmanager.cpp:1024
QgsAuthMethodConfig::name
const QString name() const
Gets name of configuration.
Definition: qgsauthconfig.h:83
QgsAuthMethod
Abstract base class for authentication method plugins.
Definition: qgsauthmethod.h:42
QgsAuthMethodEdit::configMap
virtual QgsStringMap configMap() const =0
The configuration key-vale map of subclasses.
QgsAuthManager::authMethod
QgsAuthMethod * authMethod(const QString &authMethodKey)
Gets authentication method from the config/provider cache via its key.
Definition: qgsauthmanager.cpp:1029
QgsAuthMethodConfig::setUri
void setUri(const QString &uri)
Definition: qgsauthconfig.h:89
QgsDebugMsgLevel
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
qgsauthmanager.h
QgsAuthManager::configAuthMethodKey
QString configAuthMethodKey(const QString &authcfg) const
Gets key of authentication method associated with config ID.
Definition: qgsauthmanager.cpp:1015
qgsgui.h
QgsAuthMethodConfig::setMethod
void setMethod(const QString &method)
Definition: qgsauthconfig.h:93
QgsAuthMethodEdit::validityChanged
void validityChanged(bool valid)
Emitted when the configuration validatity changes.
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsAuthConfigEdit::authenticationConfigUpdated
void authenticationConfigUpdated(const QString &authcfg)
Emit current id when an existing config is updated in auth database.
QgsAuthConfigEdit::QgsAuthConfigEdit
QgsAuthConfigEdit(QWidget *parent=nullptr, const QString &authcfg=QString(), const QString &dataprovider=QString())
Create a dialog for editing an authentication configuration.
Definition: qgsauthconfigedit.cpp:30
QgsApplication::authManager
static QgsAuthManager * authManager()
Returns the application's authentication manager instance.
Definition: qgsapplication.cpp:1436
qgsauthmethodmetadata.h
qgsapplication.h
QgsGui::enableAutoGeometryRestore
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
Definition: qgsgui.cpp:180
QgsAuthMethodConfig::setConfigMap
void setConfigMap(const QgsStringMap &map)
Set extended configuration map.
Definition: qgsauthconfig.h:125
QgsAuthMethodEdit::clearConfig
virtual void clearConfig()=0
Clear GUI controls in subclassed widget.
QgsAuthMethodConfig::setVersion
void setVersion(int version)
Sets version of the configuration.
Definition: qgsauthconfig.h:98
qgsauthconfigedit.h
QgsAuthMethodConfig::method
QString method() const
Textual key of the associated authentication method.
Definition: qgsauthconfig.h:92
QgsAuthMethodEdit::loadConfig
virtual void loadConfig(const QgsStringMap &configmap)=0
Load an existing config map into subclassed widget.
qgsauthmethodedit.h
QgsAuthMethodConfig::configMap
QgsStringMap configMap() const
Gets extended configuration, mapped to key/value pairs of QStrings.
Definition: qgsauthconfig.h:119
QgsAuthManager::authMethodMetadata
const QgsAuthMethodMetadata * authMethodMetadata(const QString &authMethodKey)
Gets authentication method metadata via its key.
Definition: qgsauthmanager.cpp:1040
QgsAuthMethod::version
int version() const
Increment this if method is significantly updated, allow updater code to be written for previously st...
Definition: qgsauthmethod.h:78
QgsAuthManager::isDisabled
bool isDisabled() const
Whether QCA has the qca-ossl plugin, which a base run-time requirement.
Definition: qgsauthmanager.cpp:487
QgsAuthMethodEdit
Abstract base class for the edit widget of authentication method plugins.
Definition: qgsauthmethodedit.h:29
QgsAuthMethodConfig::id
const QString id() const
Gets 'authcfg' 7-character alphanumeric ID of the config.
Definition: qgsauthconfig.h:78
QgsAuthConfigEdit::authenticationConfigStored
void authenticationConfigStored(const QString &authcfg)
Emit generated id when a new config is saved to auth database.
QgsAuthMethodConfig::isValid
bool isValid(bool validateid=false) const
Whether the configuration is valid.
Definition: qgsauthconfig.cpp:65
QgsAuthMethodConfig::setId
void setId(const QString &id)
Sets auth config ID.
Definition: qgsauthconfig.h:80
QgsAuthMethodEdit::validateConfig
virtual bool validateConfig()=0
Validate the configuration of subclasses.
QgsAuthManager::configIds
QStringList configIds() const
Gets list of authentication ids from database.
Definition: qgsauthmanager.cpp:3541
qgslogger.h
QgsAuthConfigIdEdit::validityChanged
void validityChanged(bool valid)
Validity of the ID has changed.
qgsauthconfigidedit.h
QgsAuthMethodConfig::setName
void setName(const QString &name)
Sets name of configuration.
Definition: qgsauthconfig.h:85
QgsAuthMethodMetadata::description
QString description() const
Returns descriptive text for the method.
Definition: qgsauthmethodmetadata.cpp:29
QgsAuthMethodConfig
Configuration storage class for authentication method configurations.
Definition: qgsauthconfig.h:41
QgsAuthMethodConfig::uri
const QString uri() const
A URI to auto-select a config when connecting to a resource.
Definition: qgsauthconfig.h:88