QGIS API Documentation 3.99.0-Master (357b655ed83)
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
19#include "qgsapplication.h"
20#include "qgsauthconfig.h"
21#include "qgsauthconfigidedit.h"
22#include "qgsauthmanager.h"
23#include "qgsauthmethodedit.h"
25#include "qgsgui.h"
26#include "qgshelp.h"
27#include "qgslogger.h"
28
29#include <QPushButton>
30#include <QString>
31
32#include "moc_qgsauthconfigedit.cpp"
33
34using namespace Qt::StringLiterals;
35
36QgsAuthConfigEdit::QgsAuthConfigEdit( QWidget *parent, const QString &authcfg, const QString &dataprovider )
37 : QDialog( parent )
38 , mAuthCfg( authcfg )
39 , mDataProvider( dataprovider )
40
41{
42 const bool disabled = QgsApplication::authManager()->isDisabled();
43 bool idok = true;
44
45 if ( !disabled && !authcfg.isEmpty() )
46 {
47 idok = QgsApplication::authManager()->configIds().contains( authcfg );
48 }
49
50 if ( disabled || !idok )
51 {
52 mAuthNotifyLayout = new QVBoxLayout;
53 this->setLayout( mAuthNotifyLayout );
54
55 QString msg( disabled ? QgsApplication::authManager()->disabledMessage() : QString() );
56 if ( !authcfg.isEmpty() )
57 {
58 msg += "\n\n" + tr( "Authentication config id not loaded: %1" ).arg( authcfg );
59 }
60 mAuthNotify = new QLabel( msg, this );
61 mAuthNotifyLayout->addWidget( mAuthNotify );
62
63 mAuthCfg.clear(); // otherwise will continue to try authenticate (and fail) after save
64 buttonBox->button( QDialogButtonBox::Save )->setEnabled( false );
65 }
66 else
67 {
68 setupUi( this );
69 connect( btnClear, &QToolButton::clicked, this, &QgsAuthConfigEdit::btnClear_clicked );
70 connect( leName, &QLineEdit::textChanged, this, &QgsAuthConfigEdit::leName_textChanged );
71 connect( buttonBox, &QDialogButtonBox::rejected, this, &QWidget::close );
72 connect( buttonBox, &QDialogButtonBox::accepted, this, &QgsAuthConfigEdit::saveConfig );
73 connect( buttonBox->button( QDialogButtonBox::Reset ), &QAbstractButton::clicked, this, &QgsAuthConfigEdit::resetConfig );
74 connect( buttonBox, &QDialogButtonBox::helpRequested, this, [] {
75 QgsHelp::openHelp( u"auth_system/auth_overview.html#authentication-configurations"_s );
76 } );
77
78 populateAuthMethods();
79
80 connect( cmbAuthMethods, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), stkwAuthMethods, &QStackedWidget::setCurrentIndex );
81 connect( cmbAuthMethods, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, [this] { validateAuth(); } );
82
83 connect( authCfgEdit, &QgsAuthConfigIdEdit::validityChanged, this, &QgsAuthConfigEdit::validateAuth );
84
85 if ( cmbAuthMethods->count() > 0 )
86 {
87 cmbAuthMethods->setCurrentIndex( 0 );
88 stkwAuthMethods->setCurrentIndex( 0 );
89 stkwAuthMethods->setSizeMode( QgsStackedWidget::SizeMode::CurrentPageOnly );
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( u"Load auth method instance FAILED for auth method key (%1)"_s.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 );
125 if ( !editWidget )
126 {
127 QgsDebugError( u"Load auth method edit widget FAILED for auth method key (%1)"_s.arg( it.value()->key() ) );
128 continue;
129 }
130 connect( editWidget, &QgsAuthMethodEdit::validityChanged, this, &QgsAuthConfigEdit::validateAuth );
131
132 cmbAuthMethods->addItem( it.key(), QVariant( it.value()->key() ) );
133 stkwAuthMethods->addWidget( editWidget );
134 }
135}
136
137void QgsAuthConfigEdit::loadConfig()
138{
139 const bool emptyAuthCfg = mAuthCfg.isEmpty();
140 authCfgEdit->setAllowEmptyId( emptyAuthCfg );
141 if ( emptyAuthCfg )
142 {
143 return;
144 }
145
146 // edit mode requires master password to have been set and verified against auth db
147 if ( !QgsApplication::authManager()->setMasterPassword( true ) )
148 {
149 mAuthCfg.clear();
150 return;
151 }
152
153 QgsAuthMethodConfig mconfig;
154 if ( !QgsApplication::authManager()->loadAuthenticationConfig( mAuthCfg, mconfig, true ) )
155 {
156 QgsDebugError( u"Loading FAILED for authcfg: %1"_s.arg( mAuthCfg ) );
157 return;
158 }
159
160 if ( !mconfig.isValid( true ) )
161 {
162 QgsDebugError( u"Loading FAILED for authcfg (%1): invalid config"_s.arg( mAuthCfg ) );
163 return;
164 }
165
166 // load basic info
167 leName->setText( mconfig.name() );
168 leResource->setText( mconfig.uri() );
169 authCfgEdit->setAuthConfigId( mconfig.id() );
170
171 const QString authMethodKey = QgsApplication::authManager()->configAuthMethodKey( mAuthCfg );
172
173 QgsDebugMsgLevel( u"Loading authcfg: %1"_s.arg( mAuthCfg ), 2 );
174 QgsDebugMsgLevel( u"Loading auth method: %1"_s.arg( authMethodKey ), 2 );
175
176 if ( authMethodKey.isEmpty() )
177 {
178 QgsDebugError( u"Loading FAILED for authcfg (%1): no auth method found"_s.arg( mAuthCfg ) );
179 return;
180 }
181
182 if ( mconfig.method() != authMethodKey )
183 {
184 QgsDebugError( u"Loading FAILED for authcfg (%1): auth method and key mismatch"_s.arg( mAuthCfg ) );
185 return;
186 }
187
188 const int indx = authMethodIndex( authMethodKey );
189 if ( indx == -1 )
190 {
191 QgsDebugError( u"Loading FAILED for authcfg (%1): no edit widget loaded for auth method '%2'"_s
192 .arg( mAuthCfg, authMethodKey ) );
193 if ( cmbAuthMethods->count() > 0 )
194 {
195 cmbAuthMethods->setCurrentIndex( 0 );
196 stkwAuthMethods->setCurrentIndex( 0 );
197 }
198 return;
199 }
200
201 cmbAuthMethods->setCurrentIndex( indx );
202 stkwAuthMethods->setCurrentIndex( indx );
203
204 QgsAuthMethodEdit *editWidget = currentEditWidget();
205 if ( !editWidget )
206 {
207 QgsDebugError( u"Cast to edit widget FAILED for authcfg (%1) and auth method key (%2)"_s
208 .arg( mAuthCfg, authMethodKey ) );
209 return;
210 }
211
212 editWidget->loadConfig( mconfig.configMap() );
213}
214
215void QgsAuthConfigEdit::resetConfig()
216{
217 clearAll();
218 loadConfig();
219 validateAuth();
220}
221
222void QgsAuthConfigEdit::saveConfig()
223{
224 if ( !QgsApplication::authManager()->setMasterPassword( true ) )
225 return;
226
227 const QString authMethodKey = cmbAuthMethods->currentData().toString();
228
229 QgsAuthMethodEdit *editWidget = currentEditWidget();
230 if ( !editWidget )
231 {
232 QgsDebugError( u"Cast to edit widget FAILED)"_s );
233 return;
234 }
235
236 QgsAuthMethod *authmethod = QgsApplication::authManager()->authMethod( authMethodKey );
237 if ( !authmethod )
238 {
239 QgsDebugError( u"Save auth config FAILED when loading auth method instance from key (%1)"_s.arg( authMethodKey ) );
240 return;
241 }
242
243 QgsAuthMethodConfig mconfig;
244 mconfig.setName( leName->text() );
245 mconfig.setUri( leResource->text() );
246 mconfig.setMethod( authMethodKey );
247 mconfig.setVersion( authmethod->version() );
248 mconfig.setConfigMap( editWidget->configMap() );
249
250 if ( !mconfig.isValid() )
251 {
252 QgsDebugError( u"Save auth config FAILED: config invalid"_s );
253 return;
254 }
255
256 const QString authCfgId( authCfgEdit->configId() );
257 if ( !mAuthCfg.isEmpty() )
258 {
259 if ( authCfgId == mAuthCfg ) // update
260 {
261 mconfig.setId( mAuthCfg );
262 if ( QgsApplication::authManager()->updateAuthenticationConfig( mconfig ) )
263 {
264 emit authenticationConfigUpdated( mAuthCfg );
265 }
266 else
267 {
268 QgsDebugError( u"Updating auth config FAILED for authcfg: %1"_s.arg( mAuthCfg ) );
269 }
270 }
271 else // store new with unique ID, then delete previous
272 {
273 mconfig.setId( authCfgId );
274 if ( QgsApplication::authManager()->storeAuthenticationConfig( mconfig ) )
275 {
276 emit authenticationConfigStored( authCfgId );
277 if ( !QgsApplication::authManager()->removeAuthenticationConfig( mAuthCfg ) )
278 {
279 QgsDebugError( u"Removal of older auth config FAILED"_s );
280 }
281 mAuthCfg = authCfgId;
282 }
283 else
284 {
285 QgsDebugError( u"Storing new auth config with user-created unique ID FAILED"_s );
286 }
287 }
288 }
289 else if ( mAuthCfg.isEmpty() )
290 {
291 if ( authCfgId.isEmpty() ) // create new with generated ID
292 {
293 if ( QgsApplication::authManager()->storeAuthenticationConfig( mconfig ) )
294 {
295 mAuthCfg = mconfig.id();
296 emit authenticationConfigStored( mAuthCfg );
297 }
298 else
299 {
300 QgsDebugError( u"Storing new auth config FAILED"_s );
301 }
302 }
303 else // create new with user-created unique ID
304 {
305 mconfig.setId( authCfgId );
306 if ( QgsApplication::authManager()->storeAuthenticationConfig( mconfig ) )
307 {
308 mAuthCfg = authCfgId;
309 emit authenticationConfigStored( mAuthCfg );
310 }
311 else
312 {
313 QgsDebugError( u"Storing new auth config with user-created unique ID FAILED"_s );
314 }
315 }
316 }
317
318 this->accept();
319}
320
321void QgsAuthConfigEdit::btnClear_clicked()
322{
323 QgsAuthMethodEdit *editWidget = currentEditWidget();
324 if ( !editWidget )
325 {
326 QgsDebugError( u"Cast to edit widget FAILED)"_s );
327 return;
328 }
329
330 editWidget->clearConfig();
331
332 validateAuth();
333}
334
335void QgsAuthConfigEdit::clearAll()
336{
337 leName->clear();
338 leResource->clear();
339 authCfgEdit->clear();
340
341 for ( int i = 0; i < stkwAuthMethods->count(); i++ )
342 {
343 QgsAuthMethodEdit *editWidget = qobject_cast<QgsAuthMethodEdit *>( stkwAuthMethods->widget( i ) );
344 if ( editWidget )
345 {
346 editWidget->clearConfig();
347 }
348 }
349
350 validateAuth();
351}
352
353void QgsAuthConfigEdit::validateAuth()
354{
355 bool authok = !leName->text().isEmpty();
356
357 QgsAuthMethodEdit *editWidget = currentEditWidget();
358 if ( !editWidget )
359 {
360 QgsDebugError( u"Cast to edit widget FAILED"_s );
361 }
362 else
363 {
364 authok = authok && editWidget->validateConfig();
365 }
366 authok = authok && authCfgEdit->validate();
367
368 buttonBox->button( QDialogButtonBox::Save )->setEnabled( authok );
369}
370
371void QgsAuthConfigEdit::leName_textChanged( const QString &txt )
372{
373 Q_UNUSED( txt )
374 validateAuth();
375}
376
377int QgsAuthConfigEdit::authMethodIndex( const QString &authMethodKey )
378{
379 return cmbAuthMethods->findData( QVariant( authMethodKey ) );
380}
381
382QgsAuthMethodEdit *QgsAuthConfigEdit::currentEditWidget()
383{
384 return qobject_cast<QgsAuthMethodEdit *>( stkwAuthMethods->currentWidget() );
385}
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.
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.
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:224
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition qgshelp.cpp:41
@ CurrentPageOnly
Only the size of the current page is considered when calculating the stacked widget size.
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:63
#define QgsDebugError(str)
Definition qgslogger.h:59