QGIS API Documentation  3.2.0-Bonn (bc43194)
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 <QHash>
21 #include <QMessageBox>
22 #include <QTimer>
23 
24 #include "qgsauthconfig.h"
25 #include "qgsauthguiutils.h"
26 #include "qgsauthmanager.h"
27 #include "qgsauthconfigedit.h"
28 #include "qgslogger.h"
29 #include "qgsapplication.h"
30 
31 
32 QgsAuthConfigSelect::QgsAuthConfigSelect( QWidget *parent, const QString &dataprovider )
33  : QWidget( parent )
34  , mDataProvider( dataprovider )
35 {
36  if ( QgsApplication::authManager()->isDisabled() )
37  {
38  mDisabled = true;
39  mAuthNotifyLayout = new QVBoxLayout;
40  this->setLayout( mAuthNotifyLayout );
41  mAuthNotify = new QLabel( QgsApplication::authManager()->disabledMessage(), this );
42  mAuthNotifyLayout->addWidget( mAuthNotify );
43  }
44  else
45  {
46  setupUi( this );
47  connect( cmbConfigSelect, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsAuthConfigSelect::cmbConfigSelect_currentIndexChanged );
48  connect( btnConfigAdd, &QToolButton::clicked, this, &QgsAuthConfigSelect::btnConfigAdd_clicked );
49  connect( btnConfigEdit, &QToolButton::clicked, this, &QgsAuthConfigSelect::btnConfigEdit_clicked );
50  connect( btnConfigRemove, &QToolButton::clicked, this, &QgsAuthConfigSelect::btnConfigRemove_clicked );
51  connect( btnConfigMsgClear, &QToolButton::clicked, this, &QgsAuthConfigSelect::btnConfigMsgClear_clicked );
52 
53  // Set icons and remove texts
54  btnConfigAdd->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/symbologyAdd.svg" ) ) );
55  btnConfigRemove->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/symbologyRemove.svg" ) ) );
56  btnConfigEdit->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionToggleEditing.svg" ) ) );
57  btnConfigMsgClear->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mIconClose.svg" ) ) );
58 
59  btnConfigAdd->setText( QStringLiteral( "" ) );
60  btnConfigRemove->setText( QStringLiteral( "" ) );
61  btnConfigEdit->setText( QStringLiteral( "" ) );
62  btnConfigMsgClear->setText( QStringLiteral( "" ) );
63 
64  leConfigMsg->setStyleSheet( QStringLiteral( "QLineEdit{background-color: %1}" )
65  .arg( QgsAuthGuiUtils::yellowColor().name() ) );
66 
67  clearConfig();
68  clearMessage();
69  populateConfigSelector();
70  }
71 }
72 
73 void QgsAuthConfigSelect::setConfigId( const QString &authcfg )
74 {
75  if ( mDisabled && mAuthNotify )
76  {
77  mAuthNotify->setText( QgsApplication::authManager()->disabledMessage() + "\n\n" +
78  tr( "Authentication config id not loaded: %1" ).arg( authcfg ) );
79  }
80  else
81  {
82  if ( mAuthCfg != authcfg )
83  {
84  mAuthCfg = authcfg;
85  }
86  populateConfigSelector();
87  loadConfig();
88  }
89 }
90 
91 void QgsAuthConfigSelect::setDataProviderKey( const QString &key )
92 {
93  if ( mDisabled )
94  {
95  return;
96  }
97 
98  mDataProvider = key;
99  populateConfigSelector();
100 }
101 
102 void QgsAuthConfigSelect::loadConfig()
103 {
104  clearConfig();
105  if ( !mAuthCfg.isEmpty() && mConfigs.contains( mAuthCfg ) )
106  {
107  QgsAuthMethodConfig config = mConfigs.value( mAuthCfg );
108  QgsAuthMethod *authmethod = QgsApplication::authManager()->configAuthMethod( mAuthCfg );
109  QString methoddesc = tr( "Missing authentication method description" );
110  if ( authmethod )
111  {
112  methoddesc = authmethod->description();
113  }
114  cmbConfigSelect->setToolTip( tr( "<ul><li><b>Method type:</b> %1</li>"
115  "<li><b>Configuration ID:</b> %2</li></ul>" ).arg( methoddesc, config.id( ) ) );
116  btnConfigEdit->setEnabled( true );
117  btnConfigRemove->setEnabled( true );
118  }
119  emit selectedConfigIdChanged( mAuthCfg );
120 }
121 
122 void QgsAuthConfigSelect::clearConfig()
123 {
124  cmbConfigSelect->setToolTip( QStringLiteral( "" ) );
125  btnConfigEdit->setEnabled( false );
126  btnConfigRemove->setEnabled( false );
127 }
128 
129 void QgsAuthConfigSelect::validateConfig()
130 {
131  if ( !mAuthCfg.isEmpty() && !mConfigs.contains( mAuthCfg ) )
132  {
133  showMessage( tr( "Configuration '%1' not in database" ).arg( mAuthCfg ) );
134  mAuthCfg.clear();
135  }
136 }
137 
138 void QgsAuthConfigSelect::populateConfigSelector()
139 {
140  loadAvailableConfigs();
141  validateConfig();
142 
143  cmbConfigSelect->blockSignals( true );
144  cmbConfigSelect->clear();
145  cmbConfigSelect->addItem( tr( "No authentication" ), "0" );
146 
147  QgsStringMap sortmap;
148  QgsAuthMethodConfigsMap::const_iterator cit = mConfigs.constBegin();
149  for ( cit = mConfigs.constBegin(); cit != mConfigs.constEnd(); ++cit )
150  {
151  QgsAuthMethodConfig config = cit.value();
152  sortmap.insert( QStringLiteral( "%1 (%2)" ).arg( config.name(), config.method() ), cit.key() );
153  }
154 
155  QgsStringMap::const_iterator sm = sortmap.constBegin();
156  for ( sm = sortmap.constBegin(); sm != sortmap.constEnd(); ++sm )
157  {
158  cmbConfigSelect->addItem( sm.key(), sm.value() );
159  }
160  cmbConfigSelect->blockSignals( false );
161 
162  int indx = 0;
163  if ( !mAuthCfg.isEmpty() )
164  {
165  indx = cmbConfigSelect->findData( mAuthCfg );
166  }
167  cmbConfigSelect->setCurrentIndex( indx > 0 ? indx : 0 );
168 }
169 
170 void QgsAuthConfigSelect::showMessage( const QString &msg )
171 {
172  if ( mDisabled )
173  {
174  return;
175  }
176  leConfigMsg->setText( msg );
177  frConfigMsg->setVisible( true );
178 }
179 
181 {
182  if ( mDisabled )
183  {
184  return;
185  }
186  leConfigMsg->clear();
187  frConfigMsg->setVisible( false );
188 }
189 
190 void QgsAuthConfigSelect::loadAvailableConfigs()
191 {
192  mConfigs.clear();
193  mConfigs = QgsApplication::authManager()->availableAuthMethodConfigs( mDataProvider );
194 }
195 
196 void QgsAuthConfigSelect::cmbConfigSelect_currentIndexChanged( int index )
197 {
198  QString authcfg = cmbConfigSelect->itemData( index ).toString();
199  mAuthCfg = ( !authcfg.isEmpty() && authcfg != QLatin1String( "0" ) ) ? authcfg : QString();
200  loadConfig();
201 }
202 
203 void QgsAuthConfigSelect::btnConfigAdd_clicked()
204 {
205  if ( !QgsApplication::authManager()->setMasterPassword( true ) )
206  return;
207 
208  QgsAuthConfigEdit *ace = new QgsAuthConfigEdit( this, QString(), mDataProvider );
209  ace->setWindowModality( Qt::WindowModal );
210  if ( ace->exec() )
211  {
212  setConfigId( ace->configId() );
213  }
214  ace->deleteLater();
215 }
216 
217 void QgsAuthConfigSelect::btnConfigEdit_clicked()
218 {
219  if ( !QgsApplication::authManager()->setMasterPassword( true ) )
220  return;
221 
222  QgsAuthConfigEdit *ace = new QgsAuthConfigEdit( this, mAuthCfg, mDataProvider );
223  ace->setWindowModality( Qt::WindowModal );
224  if ( ace->exec() )
225  {
226  //qDebug( "Edit returned config Id: %s", ace->configId().toLatin1().constData() );
227  setConfigId( ace->configId() );
228  }
229  ace->deleteLater();
230 }
231 
232 void QgsAuthConfigSelect::btnConfigRemove_clicked()
233 {
234  if ( QMessageBox::warning( this, tr( "Remove Authentication" ),
235  tr( "Are you sure that you want to permanently remove this configuration right now?\n\n"
236  "Operation can NOT be undone!" ),
237  QMessageBox::Ok | QMessageBox::Cancel,
238  QMessageBox::Cancel ) == QMessageBox::Cancel )
239  {
240  return;
241  }
242 
243  if ( QgsApplication::authManager()->removeAuthenticationConfig( mAuthCfg ) )
244  {
245  emit selectedConfigIdRemoved( mAuthCfg );
246  setConfigId( QString() );
247  }
248 }
249 
250 void QgsAuthConfigSelect::btnConfigMsgClear_clicked()
251 {
252  clearMessage();
253 }
254 
255 
257 
258 #include <QPushButton>
259 
260 QgsAuthConfigUriEdit::QgsAuthConfigUriEdit( QWidget *parent, const QString &datauri, const QString &dataprovider )
261  : QDialog( parent )
262 {
263  if ( QgsApplication::authManager()->isDisabled() )
264  {
265  mDisabled = true;
266  mAuthNotifyLayout = new QVBoxLayout;
267  this->setLayout( mAuthNotifyLayout );
268  mAuthNotify = new QLabel( QgsApplication::authManager()->disabledMessage(), this );
269  mAuthNotifyLayout->addWidget( mAuthNotify );
270  }
271  else
272  {
273  setupUi( this );
274 
275  setWindowTitle( tr( "Authentication Config ID String Editor" ) );
276 
277  buttonBox->button( QDialogButtonBox::Close )->setDefault( true );
278  connect( buttonBox, &QDialogButtonBox::rejected, this, &QWidget::close );
279  connect( buttonBox, &QDialogButtonBox::accepted, this, &QgsAuthConfigUriEdit::saveChanges );
280 
281  connect( buttonBox->button( QDialogButtonBox::Reset ), &QAbstractButton::clicked, this, &QgsAuthConfigUriEdit::resetChanges );
282 
283  connect( wdgtAuthSelect, &QgsAuthConfigSelect::selectedConfigIdChanged, this, &QgsAuthConfigUriEdit::authCfgUpdated );
284  connect( wdgtAuthSelect, &QgsAuthConfigSelect::selectedConfigIdRemoved, this, &QgsAuthConfigUriEdit::authCfgRemoved );
285 
286  wdgtAuthSelect->setDataProviderKey( dataprovider );
287  setDataSourceUri( datauri );
288  }
289 }
290 
291 void QgsAuthConfigUriEdit::setDataSourceUri( const QString &datauri )
292 {
293  if ( mDisabled )
294  {
295  return;
296  }
297  if ( datauri.isEmpty() )
298  return;
299 
300  mDataUri = mDataUriOrig = datauri;
301 
302  teDataUri->setPlainText( mDataUri );
303 
304  if ( authCfgIndex() == -1 )
305  {
306  wdgtAuthSelect->showMessage( tr( "No authcfg in Data Source URI" ) );
307  return;
308  }
309 
310  selectAuthCfgInUri();
311 
312  mAuthCfg = authCfgFromUri();
313 
314  QgsDebugMsg( QString( "Parsed authcfg ID: %1" ).arg( mAuthCfg ) );
315 
316  wdgtAuthSelect->blockSignals( true );
317  wdgtAuthSelect->setConfigId( mAuthCfg );
318  wdgtAuthSelect->blockSignals( false );
319 }
320 
322 {
323  if ( mDisabled )
324  {
325  return QString();
326  }
327  return mDataUri;
328 }
329 
330 bool QgsAuthConfigUriEdit::hasConfigId( const QString &txt )
331 {
332  if ( QgsApplication::authManager()->isDisabled() )
333  {
334  return false;
335  }
336  return QgsApplication::authManager()->hasConfigId( txt );
337 }
338 
339 void QgsAuthConfigUriEdit::saveChanges()
340 {
341  this->accept();
342 }
343 
344 void QgsAuthConfigUriEdit::resetChanges()
345 {
346  wdgtAuthSelect->clearMessage();
347  setDataSourceUri( mDataUriOrig );
348 }
349 
350 void QgsAuthConfigUriEdit::authCfgUpdated( const QString &authcfg )
351 {
352  mAuthCfg = authcfg;
353 
354  if ( mAuthCfg.size() != 7 )
355  {
356  mAuthCfg.clear();
357  removeAuthCfgFromUri();
358  }
359  else
360  {
361  updateUriWithAuthCfg();
362  }
363  teDataUri->clear();
364  teDataUri->setPlainText( mDataUri );
365  selectAuthCfgInUri();
366 }
367 
368 void QgsAuthConfigUriEdit::authCfgRemoved( const QString &authcfg )
369 {
370  if ( authCfgFromUri() == authcfg )
371  {
372  removeAuthCfgFromUri();
373  }
374 }
375 
376 int QgsAuthConfigUriEdit::authCfgIndex()
377 {
378  QRegExp rx( QgsApplication::authManager()->configIdRegex() );
379  return rx.indexIn( mDataUri );
380 }
381 
382 QString QgsAuthConfigUriEdit::authCfgFromUri()
383 {
384  int startindex = authCfgIndex();
385  if ( startindex == -1 )
386  return QString();
387 
388  return mDataUri.mid( startindex + 8, 7 );
389 }
390 
391 void QgsAuthConfigUriEdit::selectAuthCfgInUri()
392 {
393  int startindex = authCfgIndex();
394  if ( startindex == -1 )
395  return;
396 
397  // authcfg=.{7} will always be 15 chars
398  QTextCursor tc = teDataUri->textCursor();
399  tc.setPosition( startindex );
400  tc.setPosition( startindex + 15, QTextCursor::KeepAnchor );
401  teDataUri->setTextCursor( tc );
402  teDataUri->setFocus();
403 }
404 
405 void QgsAuthConfigUriEdit::updateUriWithAuthCfg()
406 {
407  int startindex = authCfgIndex();
408  if ( startindex == -1 )
409  {
410  if ( mAuthCfg.size() == 7 )
411  {
412  wdgtAuthSelect->showMessage( tr( "Adding authcfg to URI not supported" ) );
413  }
414  return;
415  }
416 
417  mDataUri = mDataUri.replace( startindex + 8, 7, mAuthCfg );
418 }
419 
420 void QgsAuthConfigUriEdit::removeAuthCfgFromUri()
421 {
422  int startindex = authCfgIndex();
423  if ( startindex == -1 )
424  return;
425 
426  // add any preceding space so two spaces will not result after removal
427  int rmvlen = 15;
428  if ( startindex - 1 >= 0
429  && ( mDataUri.at( startindex - 1 ).isSpace()
430  || mDataUri.at( startindex - 1 ) == QChar( '&' ) ) )
431  {
432  startindex -= 1;
433  rmvlen += 1;
434  }
435 
436  // trim any leftover spaces or & from ends
437  mDataUri = mDataUri.remove( startindex, rmvlen ).trimmed();
438  if ( mDataUri.at( 0 ) == QChar( '&' ) )
439  mDataUri = mDataUri.remove( 0, 1 );
440 
441  // trim any & from
442 
443  mAuthCfg.clear();
444 }
445 
static bool hasConfigId(const QString &txt)
Whether a string contains an authcfg ID.
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
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.
void clearMessage()
Clear and hide small message bar.
QString dataSourceUri()
The returned, possibly edited data source URI.
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
static QColor yellowColor()
Yellow color representing caution regarding action.
QgsAuthConfigSelect(QWidget *parent=nullptr, const QString &dataprovider=QString())
Create a dialog for setting an associated authentication config, either from existing configs...
QMap< QString, QString > QgsStringMap
Definition: qgis.h:501
void showMessage(const QString &msg)
Show a small message bar with a close button.
void setDataProviderKey(const QString &key)
Sets key of layer provider, if applicable.
virtual QString description() const =0
A non-translated short description representing the auth method for use in debug output and About dia...
bool hasConfigId(const QString &txt) const
Returns whether a string includes an authcfg ID token.
QgsAuthMethodConfigsMap availableAuthMethodConfigs(const QString &dataprovider=QString())
Gets mapping of authentication config ids and their base configs (not decrypted data) ...
void setConfigId(const QString &authcfg)
Sets the authentication config id for the resource.
Configuration storage class for authentication method configurations.
Definition: qgsauthconfig.h:38
const QString name() const
Gets name of configuration.
Definition: qgsauthconfig.h:64
void selectedConfigIdChanged(const QString &authcfg)
Emitted when authentication config is changed or missing.
static QgsAuthManager * authManager()
Returns the application&#39;s authentication manager instance.
QgsAuthMethod * configAuthMethod(const QString &authcfg)
Gets authentication method from the config/provider cache.
Abstract base class for authentication method plugins.
Definition: qgsauthmethod.h:36
void setDataSourceUri(const QString &datauri)
Sets the data source URI to parse.
QString method() const
Textual key of the associated authentication method.
Definition: qgsauthconfig.h:73
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...
const QString id() const
Gets &#39;authcfg&#39; 7-character alphanumeric ID of the config.
Definition: qgsauthconfig.h:59
void selectedConfigIdRemoved(const QString &authcfg)
Emitted when authentication config is removed.