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