UltraScan III
us_database.cpp
Go to the documentation of this file.
1 #include "us_database.h"
3 #include "us_gui_settings.h"
4 #include "us_settings.h"
5 #include "us_passwd.h"
6 #include "us_help.h"
7 #include "us_crypto.h"
8 #include "us_db2.h"
9 
10 US_Database::US_Database( QWidget* w, Qt::WindowFlags flags )
11  : US_Widgets( true, w, flags )
12 {
13  uuid.clear();
14 
15  // Frame layout
16  setPalette( US_GuiSettings::frameColor() );
17 
18  setWindowTitle( "Database Configuration" );
19  setAttribute( Qt::WA_DeleteOnClose );
20 
21  QByteArray currentHash = US_Settings::UltraScanPW();
22 
23  if ( currentHash.isEmpty() )
24  {
25  QMessageBox::information( this,
26  tr( "No master password" ),
27  tr( "The Master Password has not been set." ) );
28  close();
29  }
30 
31  QBoxLayout* topbox = new QVBoxLayout( this );
32  topbox->setSpacing( 2 );
33 
34  // Set up the database list window
35  QLabel* banner = us_banner( tr( "Database List" ) );
36  topbox->addWidget( banner );
37 
38  QLabel* banner2 = us_banner(
39  tr( "(Doubleclick for details and set the default)" ), -1 );
40  topbox->addWidget( banner2 );
41 
42  lw_entries = new QListWidget();
43  lw_entries->setSortingEnabled( true );
44  lw_entries->setPalette( US_GuiSettings::editColor() );
45  lw_entries->setFont( QFont( US_GuiSettings::fontFamily(),
47  topbox->addWidget( lw_entries );
48 
49  // Populate db_list
50  QStringList DB = US_Settings::defaultDB();
51  QString defaultDB;
52  if ( DB.size() > 0 ) defaultDB = US_Settings::defaultDB().at( 0 );
53  update_lw( defaultDB );
54 
55  connect( lw_entries, SIGNAL( itemDoubleClicked( QListWidgetItem* ) ),
56  SLOT ( select_db ( QListWidgetItem* ) ) );
57  // Detail info
58  QLabel* info = us_banner( tr( "Database Detailed Information" ) );
59  topbox->addWidget( info );
60 
61  int row = 0;
62  QGridLayout* details = new QGridLayout();
63 
64  // Row 1
65  QLabel* desc = us_label( "Database Description:" );
66  details->addWidget( desc, row, 0 );
67 
68  le_description = us_lineedit( "", 0 );
69  details->addWidget( le_description, row++, 1 );
70 
71  // Row 2
72  QLabel* user = us_label( "DB Connection Name:" );
73  details->addWidget( user, row, 0 );
74 
75  le_username = us_lineedit( "", 0 );
76  details->addWidget( le_username, row++, 1 );
77 
78  // Row 3
79  QLabel* password = us_label( "DB Password:" );
80  details->addWidget( password, row, 0 );
81 
82  le_password = us_lineedit( "", 0 );
83  le_password->setEchoMode( QLineEdit::Password );
84  details->addWidget( le_password, row++, 1 );
85 
86  // Row 4
87  QLabel* DBname = us_label( "Database Name:" );
88  details->addWidget( DBname, row, 0 );
89 
90  le_dbname = us_lineedit( "", 0 );
91  details->addWidget( le_dbname, row++, 1 );
92 
93  // Row 5
94  QLabel* host = us_label( "Host Address:" );
95  details->addWidget( host, row, 0 );
96 
97  le_host = us_lineedit( "", 0 );
98  details->addWidget( le_host, row++, 1 );
99 
100  // Row 6
101  QLabel* investigator = us_label( "Investigator Email:" );
102  details->addWidget( investigator, row, 0 );
103 
105 
106  // Make the line edit entries wider
107  QFontMetrics fm( le_investigator_email->font() );
108  le_investigator_email->setMinimumWidth( fm.maxWidth() * 10 );
109 
110  details->addWidget( le_investigator_email, row++, 1 );
111 
112  // Row 7
113  QLabel* investigator_pw = us_label( "Investigator Password:" );
114  details->addWidget( investigator_pw, row, 0 );
115 
116  le_investigator_pw = us_lineedit( "", 0 );
117  le_investigator_pw->setEchoMode( QLineEdit::Password );
118  details->addWidget( le_investigator_pw, row++, 1 );
119 
120  topbox->addLayout( details );
121 
122  //Pushbuttons
123  row = 0;
124  QGridLayout* buttons = new QGridLayout();
125 
126  pb_save = us_pushbutton( tr( "Save Entry" ) );
127  pb_save->setEnabled( false );
128  connect( pb_save, SIGNAL( clicked() ), this, SLOT( check_add() ) );
129  buttons->addWidget( pb_save, row, 0 );
130 
131  pb_delete = us_pushbutton( tr( "Delete Current Entry" ) );
132  pb_delete->setEnabled( false );
133  connect( pb_delete, SIGNAL( clicked() ), this, SLOT( deleteDB() ) );
134  buttons->addWidget( pb_delete, row++, 1 );
135 
136  pb_testConnect = us_pushbutton( tr( "Test Database Connectivity" ) );
137  connect( pb_testConnect, SIGNAL( clicked() ), this, SLOT( test_connect() ) );
138  buttons->addWidget( pb_testConnect, row++, 0, 1, 2 );
139 
140  QHBoxLayout* std_buttons = new QHBoxLayout;
141 
142  pb_reset = us_pushbutton( tr( "Reset" ) );
143  connect( pb_reset, SIGNAL( clicked() ), this, SLOT( reset() ) );
144  std_buttons->addWidget( pb_reset );
145 
146  QPushButton* pb_help = us_pushbutton( tr( "Help" ) );
147  connect( pb_help, SIGNAL( clicked() ), this, SLOT( help() ) );
148  std_buttons->addWidget( pb_help );
149 
150  QPushButton* pb_cancel = us_pushbutton( tr( "Close" ) );
151  connect( pb_cancel, SIGNAL( clicked() ), this, SLOT( close() ) );
152  std_buttons->addWidget( pb_cancel );
153 
154  topbox->addLayout( buttons );
155  topbox->addLayout( std_buttons );
156 }
157 
158 void US_Database::select_db( QListWidgetItem* entry )
159 {
160  // When this is run, we will always have a current dblist
161 
162  // Delete trailing (default) if that is present
163  QString item = entry->text().remove( " (default)" );
164 
165  // Get the master PW
166  US_Passwd pw;
167  QString master_pw = pw.getPasswd();
168 
169  for ( int i = 0; i < dblist.size(); i++ )
170  {
171  if ( item == dblist.at( i ).at( 0 ) )
172  {
173  le_description ->setText( item );
174  le_username ->setText( dblist.at( i ).at( 1 ) );
175  le_dbname ->setText( dblist.at( i ).at( 2 ) );
176  le_host ->setText( dblist.at( i ).at( 3 ) );
177  le_investigator_email->setText( dblist.at( i ).at( 6 ) );
178 
179  // DB Logon PW
180  QString cipher = dblist.at( i ).at( 4 );
181  QString iv = dblist.at( i ).at( 5 );
182  QString pw_string = US_Crypto::decrypt( cipher, master_pw, iv );
183  le_password->setText( pw_string );
184 
185  // DB Internal PW
186  cipher = dblist.at( i ).at( 7 );
187  iv = dblist.at( i ).at( 8 );
188  pw_string = US_Crypto::decrypt( cipher, master_pw, iv );
189  le_investigator_pw->setText( pw_string );
190 
191  uuid = dblist.at( i ).at( 9 );
192 
193  // Set the default DB and user for that DB
195 
196  update_inv();
197  update_lw( item );
198 
199  QMessageBox::information( this,
200  tr( "Database Selected" ),
201  tr( "The default database has been updated." ) );
202  pb_save ->setEnabled( true );
203  pb_delete->setEnabled( true );
204 
205  break;
206  }
207  }
208 }
209 
211 {
212  US_Passwd pw;
213  US_DB2 db( pw.getPasswd() );
214 
215  if ( db.lastErrno() != US_DB2::OK )
216  {
217  QMessageBox::information( this,
218  tr( "Error" ),
219  tr( "Error making the DB connection.\n" ) );
220 
221  return;
222  }
223 
224  QStringList q( "get_user_info" );
225  db.query( q );
226  db.next();
227 
228  int ID = db.value( 0 ).toInt();
229  QString fname = db.value( 1 ).toString();
230  QString lname = db.value( 2 ).toString();
231  int level = db.value( 5 ).toInt();
232 
233  US_Settings::set_us_inv_name ( lname + ", " + fname );
236 }
237 
239 {
240  // Check that all fields have at least something
241  if ( le_description->text().isEmpty() )
242  {
243  QMessageBox::information( this,
244  tr( "Attention" ),
245  tr( "Please enter a Description before saving..." ) );
246  return;
247  }
248 
249  if ( le_username->text().isEmpty() )
250  {
251  QMessageBox::information( this,
252  tr( "Attention" ),
253  tr( "Please enter a User Name before saving..." ) );
254  return;
255  }
256 
257  if ( le_password->text().isEmpty() )
258  {
259  QMessageBox::information( this,
260  tr( "Attention" ),
261  tr( "Please enter a Password before saving..." ) );
262  return;
263  }
264 
265  if ( le_dbname->text().isEmpty() )
266  {
267  QMessageBox::information( this,
268  tr( "Attention" ),
269  tr( "Please enter a Database Name before saving..."));
270  return;
271  }
272 
273  if ( le_host->text().isEmpty() )
274  {
275  QMessageBox::information( this,
276  tr( "Attention" ),
277  tr( "Please enter a Host Address (possibly 'localhost') "
278  "before saving..." ) );
279  return;
280  }
281 
282  if ( le_investigator_email->text().isEmpty() )
283  {
284  QMessageBox::information( this,
285  tr( "Attention" ),
286  tr( "Please enter an investigator email address "
287  "before saving..." ) );
288  return;
289  }
290 
291  if ( le_investigator_pw->text().isEmpty() )
292  {
293  QMessageBox::information( this,
294  tr( "Attention" ),
295  tr( "Please enter an investigator password "
296  "before saving..." ) );
297  return;
298  }
299 
300  if ( uuid.isEmpty() )
301  {
302  if ( ! test_connect() ) return;
303  }
304 
305  // Get the master PW
306  US_Passwd pw;
307  QString master_pw = pw.getPasswd();
308 
309  // Encrypt the DB and investigator passwords with the master password
310  QString password = le_password->text();
311  QStringList pw_list = US_Crypto::encrypt( password , master_pw );
312 
313  password = le_investigator_pw->text();
314  QStringList inv_pw = US_Crypto::encrypt( password, master_pw );
315 
316  // Save the DB entry
318  bool updated = false;
319 
320  for ( int i = 0; i < dblist.size(); i++ )
321  {
322  QStringList db = dblist.at( i );
323  if ( db.at( 0 ) == le_description->text() )
324  {
325  db.replace( 1, le_username->text() );
326  db.replace( 2, le_dbname ->text() );
327  db.replace( 3, le_host ->text() );
328  db.replace( 4, pw_list.at( 0 ) ); // Encrypted password
329  db.replace( 5, pw_list.at( 1 ) ); // Initialization vector
330  db.replace( 6, le_investigator_email->text() );
331  db.replace( 7, inv_pw.at( 0 ) );
332  db.replace( 8, inv_pw.at( 1 ) );
333  db.replace( 9, uuid );
334 
335  dblist.replace( i, db );
336  updated = true;
337  break;
338  }
339  }
340 
341  if ( ! updated )
342  {
343  QStringList entry;
344  entry << le_description->text()
345  << le_username->text()
346  << le_dbname->text()
347  << le_host->text()
348  << pw_list.at( 0 )
349  << pw_list.at( 1 )
350  << le_investigator_email->text()
351  << inv_pw.at( 0 )
352  << inv_pw.at( 1 )
353  << uuid;
354 
355  dblist << entry;
356  }
357 
358  // Update the list widget
360  update_lw( le_description->text() );
361 
362  if ( lw_entries->count() == 1 ) save_default();
363 
364  pb_save ->setEnabled( true );
365  pb_delete->setEnabled( true );
366 }
367 
368 void US_Database::update_lw( const QString& current )
369 {
370  lw_entries->clear();
371 
373  QStringList defaultDB = US_Settings::defaultDB();
374  QString defaultDBname;
375 
376  if ( defaultDB.size() > 0 ) defaultDBname = defaultDB.at( 0 );
377 
378  for ( int i = 0; i < dblist.size(); i++ )
379  {
380  QString desc = dblist.at( i ).at( 0 );
381  QString display = desc;
382 
383  if ( desc == defaultDBname ) display.append( " (default)" );
384 
385  QListWidgetItem* widget = new QListWidgetItem( display );
386  lw_entries->addItem( widget );
387 
388  if ( desc == current )
389  lw_entries->setCurrentItem( widget, QItemSelectionModel::Select );
390  }
391 }
392 
393 void US_Database::reset( void )
394 {
395  QStringList DB = US_Settings::defaultDB();
396  QString defaultDB;
397  if ( DB.size() > 0 ) defaultDB = US_Settings::defaultDB().at( 0 );
398  update_lw( defaultDB );
399 
400  le_description ->setText("");
401  le_username ->setText("");
402  le_password ->setText("");
403  le_dbname ->setText("");
404  le_host ->setText("");
405  le_investigator_email->setText("");
406  le_investigator_pw ->setText("");
407  uuid = "";
408 
409  pb_save ->setEnabled( false );
410  pb_delete ->setEnabled( false );
411 }
412 
413 void US_Database::help( void )
414 {
415  US_Help* showhelp = new US_Help(this);
416  showhelp->show_help( "database_config.html" );
417 }
418 
420 {
421  for ( int i = 0; i < dblist.size(); i++ )
422  {
423  QString desc = dblist.at( i ).at( 0 );
424 
425  // Look for the current description
426  if ( desc == le_description->text() )
427  {
428  if ( dblist.at( i ).at( 9 ) == "" )
429  {
430  QMessageBox::information( this,
431  tr( "Default Database Problem" ),
432  tr( "The current database information has not been tested "
433  "for connectivity.\n"
434  "The default database has not been updated.") );
435  return;
436  }
437 
438  QString null = "";
439 
441  update_inv();
442  reset();
443 
444  QMessageBox::information( this,
445  tr( "Default Database" ),
446  tr( "The default database has been updated." ) );
447  return;
448  }
449  }
450 
451  QMessageBox::warning( this,
452  tr( "Default Database Problem" ),
453  tr( "The description does not match any in the database list.\n"
454  "The default database has not been updated." ) );
455 }
456 
458 {
459  QString item = le_description->text();
460 
461  // Go through list and delete the one matching description
462  for ( int i = 0; i < dblist.size(); i++ )
463  {
464  QString desc = dblist.at( i ).at( 0 );
465 
466  // Look for the current description
467  if ( desc == item )
468  {
469  dblist.removeAt( i );
471 
472  // Check if the default DB matches
473  QStringList defaultDB = US_Settings::defaultDB();
474 
475  if ( defaultDB.at( 0 ) == item )
476  US_Settings::set_defaultDB( QStringList() );
477 
478  reset();
479 
480  QMessageBox::information( this,
481  tr( "Database Removed" ),
482  tr( "The database has been removed." ) );
483  return;
484  }
485  }
486 
487  QMessageBox::warning( this,
488  tr( "Database Problem" ),
489  tr( "The description does not match any in the database list.\n"
490  "The database has not been removed." ) );
491 }
492 
494 {
495  if ( le_host ->text().isEmpty() ||
496  le_dbname ->text().isEmpty() ||
497  le_username ->text().isEmpty() ||
498  le_password ->text().isEmpty() ||
499  le_investigator_email->text().isEmpty() ||
500  le_investigator_pw ->text().isEmpty() )
501  {
502  QMessageBox::warning( this,
503  tr( "Missing Data" ),
504  tr( "Please fill in all fields before testing the connection." ) );
505 
506  return false;
507  }
508 
509  QString error;
510  US_DB2 db;
511 //qDebug() << "USCFG: call test_secure...";
512  bool ok = db.test_secure_connection(
513  le_host ->text(), le_dbname ->text(),
514  le_username ->text(), le_password ->text(),
515  le_investigator_email->text(), le_investigator_pw->text(),
516  error );
517  if ( ok )
518  {
519  uuid = db.value( 0 ).toString(); // Set class variable uuid
520 
521  // Make sure the uuid is updated in the dblist structure
522  for ( int i = 0; i < dblist.size(); i++ )
523  {
524  QString desc = dblist.at( i ).at( 0 );
525 
526  // Look for the current description
527  if ( desc == le_description->text() )
528  {
529  QStringList list = dblist.at( i );
530  list.replace( 9, uuid );
531  dblist.replace( i, list );
533  break;
534  }
535  }
536 
537  QMessageBox::information( this,
538  tr( "Database Connection" ),
539  tr( "The connection was successful." ) );
540 
541  pb_save->setEnabled( true );
542  }
543  else
544  QMessageBox::warning( this,
545  tr( "Database Connection" ),
546  tr( "The connection failed.\n" ) + error );
547 
548  return ok;
549 }