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