Package Gnumed :: Package wxpython :: Module gmAuthWidgets
[frames] | no frames]

Source Code for Module Gnumed.wxpython.gmAuthWidgets

  1  """GNUmed authentication widgets. 
  2   
  3  This module contains widgets and GUI 
  4  functions for authenticating users. 
  5  """ 
  6  #================================================================ 
  7  __version__ = "$Revision: 1.45 $" 
  8  __author__ = "karsten.hilbert@gmx.net, H.Herb, H.Berger, R.Terry" 
  9  __license__ = "GPL (details at http://www.gnu.org)" 
 10   
 11   
 12  # stdlib 
 13  import sys, os.path, logging, re as regex 
 14   
 15   
 16  # 3rd party 
 17  import wx 
 18   
 19   
 20  # GNUmed 
 21  if __name__ == '__main__': 
 22          sys.path.insert(0, '../../') 
 23  from Gnumed.pycommon import gmLoginInfo, gmPG2, gmBackendListener, gmTools, gmCfg2, gmI18N 
 24  from Gnumed.business import gmSurgery 
 25  from Gnumed.wxpython import gmGuiHelpers, gmExceptionHandlingWidgets 
 26   
 27   
 28  _log = logging.getLogger('gm.ui') 
 29  _log.info(__version__) 
 30  _cfg = gmCfg2.gmCfgData() 
 31   
 32  try: 
 33          _('dummy-no-need-to-translate-but-make-epydoc-happy') 
 34  except NameError: 
 35          _ = lambda x:x 
 36   
 37   
 38  msg_generic = _(""" 
 39  GNUmed database version mismatch. 
 40   
 41  This database version cannot be used with this client: 
 42   
 43   client version: %s 
 44   database version detected: %s 
 45   database version needed: %s 
 46   
 47  Currently connected to database: 
 48   
 49   host: %s 
 50   database: %s 
 51   user: %s 
 52  """) 
 53   
 54  msg_time_skew_fail = _("""\ 
 55  The server and client clocks are off 
 56  by more than %s minutes ! 
 57   
 58  You must fix the time settings before 
 59  you can use this database with this 
 60  client. 
 61   
 62  You may have to contact your 
 63  administrator for help.""") 
 64   
 65  msg_time_skew_warn = _("""\ 
 66  The server and client clocks are off 
 67  by more than %s minutes ! 
 68   
 69  You should fix the time settings. 
 70  Otherwise clinical data may appear to 
 71  have been entered at the wrong time. 
 72   
 73  You may have to contact your 
 74  administrator for help.""") 
 75   
 76  msg_insanity = _(""" 
 77  There is a serious problem with the database settings: 
 78   
 79  %s 
 80   
 81  You may have to contact your administrator for help.""") 
 82   
 83  msg_fail = _(""" 
 84  You must connect to a different database in order 
 85  to use the GNUmed client. You may have to contact 
 86  your administrator for help.""") 
 87   
 88  msg_override = _(""" 
 89  The client will, however, continue to start up because 
 90  you are running a development/test version of GNUmed. 
 91   
 92  There may be schema related errors. Please report and/or 
 93  fix them. Do not rely on this database to work properly 
 94  in all cases !""") 
 95   
 96  #================================================================ 
 97  # convenience functions 
 98  #---------------------------------------------------------------- 
99 -def connect_to_database(max_attempts=3, expected_version=None, require_version=True):
100 """Display the login dialog and try to log into the backend. 101 102 - up to max_attempts times 103 - returns True/False 104 """ 105 # force programmer to set a valid expected_version 106 expected_hash = gmPG2.known_schema_hashes[expected_version] 107 client_version = _cfg.get(option = u'client_version') 108 global current_db_name 109 current_db_name = u'gnumed_%s' % expected_version 110 111 attempt = 0 112 113 dlg = cLoginDialog(None, -1, client_version = client_version) 114 dlg.Centre(wx.BOTH) 115 116 while attempt < max_attempts: 117 118 _log.debug('login attempt %s of %s', (attempt+1), max_attempts) 119 120 connected = False 121 122 dlg.ShowModal() 123 login = dlg.panel.GetLoginInfo() 124 if login is None: 125 _log.info("user cancelled login dialog") 126 break 127 128 # try getting a connection to verify the DSN works 129 dsn = gmPG2.make_psycopg2_dsn ( 130 database = login.database, 131 host = login.host, 132 port = login.port, 133 user = login.user, 134 password = login.password 135 ) 136 try: 137 conn = gmPG2.get_raw_connection(dsn = dsn, verbose = True, readonly = True) 138 connected = True 139 140 except gmPG2.cAuthenticationError, e: 141 attempt += 1 142 _log.error(u"login attempt failed: %s", e) 143 if attempt < max_attempts: 144 if (u'host=127.0.0.1' in (u'%s' % e)) or (u'host=' not in (u'%s' % e)): 145 msg = _( 146 'Unable to connect to database:\n\n' 147 '%s\n\n' 148 "Are you sure you have got a local database installed ?\n" 149 '\n' 150 "Please retry with proper credentials or cancel.\n" 151 '\n' 152 'You may also need to check the PostgreSQL client\n' 153 'authentication configuration in pg_hba.conf. For\n' 154 'details see:\n' 155 '\n' 156 'wiki.gnumed.de/bin/view/Gnumed/ConfigurePostgreSQL' 157 ) 158 else: 159 msg = _( 160 "Unable to connect to database:\n\n" 161 "%s\n\n" 162 "Please retry with proper credentials or cancel.\n" 163 "\n" 164 'You may also need to check the PostgreSQL client\n' 165 'authentication configuration in pg_hba.conf. For\n' 166 'details see:\n' 167 '\n' 168 'wiki.gnumed.de/bin/view/Gnumed/ConfigurePostgreSQL' 169 ) 170 msg = msg % e 171 msg = regex.sub(r'password=[^\s]+', u'password=%s' % gmTools.u_replacement_character, msg) 172 gmGuiHelpers.gm_show_error ( 173 msg, 174 _('Connecting to backend') 175 ) 176 del e 177 continue 178 179 except gmPG2.dbapi.OperationalError, e: 180 _log.error(u"login attempt failed: %s", e) 181 msg = _( 182 "Unable to connect to database:\n\n" 183 "%s\n\n" 184 "Please retry another backend / user / password combination !\n" 185 ) % gmPG2.extract_msg_from_pg_exception(e) 186 msg = regex.sub(r'password=[^\s]+', u'password=%s' % gmTools.u_replacement_character, msg) 187 gmGuiHelpers.gm_show_error ( 188 msg, 189 _('Connecting to backend') 190 ) 191 del e 192 continue 193 194 # connect was successful 195 gmPG2.set_default_login(login = login) 196 gmPG2.set_default_client_encoding(encoding = dlg.panel.backend_profile.encoding) 197 198 compatible = gmPG2.database_schema_compatible(version = expected_version) 199 if compatible or not require_version: 200 dlg.panel.save_state() 201 202 if not compatible: 203 connected_db_version = gmPG2.get_schema_version() 204 msg = msg_generic % ( 205 client_version, 206 connected_db_version, 207 expected_version, 208 gmTools.coalesce(login.host, '<localhost>'), 209 login.database, 210 login.user 211 ) 212 if require_version: 213 gmGuiHelpers.gm_show_error(msg + msg_fail, _('Verifying database version')) 214 connected = False 215 continue 216 gmGuiHelpers.gm_show_info(msg + msg_override, _('Verifying database version')) 217 218 # FIXME: make configurable 219 max_skew = 1 # minutes 220 if _cfg.get(option = 'debug'): 221 max_skew = 10 222 if not gmPG2.sanity_check_time_skew(tolerance = (max_skew * 60)): 223 if _cfg.get(option = 'debug'): 224 gmGuiHelpers.gm_show_warning(msg_time_skew_warn % max_skew, _('Verifying database settings')) 225 else: 226 gmGuiHelpers.gm_show_error(msg_time_skew_fail % max_skew, _('Verifying database settings')) 227 connected = False 228 continue 229 230 sanity_level, message = gmPG2.sanity_check_database_settings() 231 if sanity_level != 0: 232 gmGuiHelpers.gm_show_error((msg_insanity % message), _('Verifying database settings')) 233 if sanity_level == 2: 234 connected = False 235 continue 236 237 gmExceptionHandlingWidgets.set_is_public_database(login.public_db) 238 gmExceptionHandlingWidgets.set_helpdesk(login.helpdesk) 239 240 listener = gmBackendListener.gmBackendListener(conn = conn) 241 break 242 243 dlg.Destroy() 244 245 return connected
246 #================================================================
247 -def get_dbowner_connection(procedure=None, dbo_password=None):
248 if procedure is None: 249 procedure = _('<restricted procedure>') 250 251 # 1) get password for gm-dbo 252 if dbo_password is None: 253 pwd_gm_dbo = wx.GetPasswordFromUser ( 254 message = _(""" 255 [%s] 256 257 This is a restricted procedure. We need the 258 password for the GNUmed database owner. 259 260 Please enter the password for <gm-dbo>:""") % procedure, 261 caption = procedure 262 ) 263 if pwd_gm_dbo == '': 264 return None 265 else: 266 pwd_gm_dbo = dbo_password 267 268 # 2) connect as gm-dbo 269 login = gmPG2.get_default_login() 270 dsn = gmPG2.make_psycopg2_dsn(database=login.database, host=login.host, port=login.port, user='gm-dbo', password=pwd_gm_dbo) 271 try: 272 conn = gmPG2.get_connection(dsn=dsn, readonly=False, verbose=True, pooled=False) 273 except: 274 _log.exception('cannot connect') 275 gmGuiHelpers.gm_show_error ( 276 aMessage = _('Cannot connect as the GNUmed database owner <gm-dbo>.'), 277 aTitle = procedure 278 ) 279 return None 280 281 return conn
282 #================================================================
283 -class cBackendProfile:
284 pass
285 #================================================================
286 -class cLoginDialog(wx.Dialog):
287 """cLoginDialog - window holding cLoginPanel""" 288
289 - def __init__(self, parent, id, title=_("Welcome to the"), client_version=u'*** unknown ***'):
290 wx.Dialog.__init__(self, parent, id, title) 291 self.panel = cLoginPanel(self, -1, isDialog=1, client_version = client_version) 292 self.Fit() # needed for Windoze. 293 self.Centre() 294 295 self.SetIcon(gmTools.get_icon(wx = wx))
296 #================================================================
297 -class cLoginPanel(wx.Panel):
298 """GUI panel class that interactively gets Postgres login parameters. 299 300 It features combo boxes which "remember" any number of 301 previously entered settings. 302 """
303 - def __init__(self, parent, id, 304 pos = wx.DefaultPosition, size = wx.DefaultSize, style = wx.TAB_TRAVERSAL, 305 isDialog = 0, client_version = u'*** unknown ***'):
306 """Create login panel. 307 308 isDialog: if this panel is the main panel of a dialog, the panel will 309 resize the dialog automatically to display everything neatly 310 if isDialog is set to True 311 """ 312 wx.Panel.__init__(self, parent, id, pos, size, style) 313 self.parent = parent 314 315 #True if dialog was cancelled by user 316 #if the dialog is closed manually, login should be cancelled 317 self.cancelled = True 318 319 # True if this panel is displayed within a dialog (will resize the dialog automatically then) 320 self.isDialog = isDialog 321 322 self.topsizer = wx.BoxSizer(wx.VERTICAL) 323 324 # find bitmap 325 paths = gmTools.gmPaths(app_name = u'gnumed', wx = wx) 326 bitmap = os.path.join(paths.system_app_data_dir, 'bitmaps', 'gnumedlogo.png') 327 try: 328 png = wx.Image(bitmap, wx.BITMAP_TYPE_PNG).ConvertToBitmap() 329 bmp = wx.StaticBitmap(self, -1, png, wx.Point(10, 10), wx.Size(png.GetWidth(), png.GetHeight())) 330 self.topsizer.Add ( 331 bmp, 332 proportion = 0, 333 flag = wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 334 border = 10 335 ) 336 except: 337 self.topsizer.Add ( 338 wx.StaticText ( 339 self, 340 -1, 341 label = _("Cannot find image") + bitmap, 342 style = wx.ALIGN_CENTRE 343 ), 344 proportion = 0, 345 flag = wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 346 border = 10 347 ) 348 349 paramsbox_caption = _('"%s" (version %s)') % (gmSurgery.gmCurrentPractice().active_workplace, client_version) 350 351 # FIXME: why doesn't this align in the centre ? 352 self.paramsbox = wx.StaticBox( self, -1, paramsbox_caption, style = wx.ALIGN_CENTRE_HORIZONTAL) 353 self.paramsboxsizer = wx.StaticBoxSizer( self.paramsbox, wx.VERTICAL ) 354 self.paramsbox.SetForegroundColour(wx.Colour(35, 35, 142)) 355 self.paramsbox.SetFont(wx.Font( 356 pointSize = 12, 357 family = wx.SWISS, 358 style = wx.NORMAL, 359 weight = wx.BOLD, 360 underline = False 361 )) 362 self.pboxgrid = wx.FlexGridSizer(5, 2, 5, 5) 363 self.pboxgrid.AddGrowableCol(1) 364 365 # PROFILE COMBO 366 label = wx.StaticText( self, -1, _('Log into'), wx.DefaultPosition, wx.DefaultSize, 0) 367 label.SetForegroundColour(wx.Colour(35, 35, 142)) 368 self.pboxgrid.Add(label, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5) 369 self.__backend_profiles = self.__get_backend_profiles() 370 self._CBOX_profile = wx.ComboBox ( 371 self, 372 -1, 373 self.__backend_profiles.keys()[0], 374 wx.DefaultPosition, 375 size = wx.Size(150,-1), 376 choices = self.__backend_profiles.keys(), 377 style = wx.CB_READONLY 378 ) 379 self.pboxgrid.Add (self._CBOX_profile, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) 380 381 # USER NAME COMBO 382 label = wx.StaticText( self, -1, _("Username"), wx.DefaultPosition, wx.DefaultSize, 0 ) 383 label.SetForegroundColour(wx.Colour(35, 35, 142)) 384 self.pboxgrid.Add(label, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 ) 385 self.__previously_used_accounts = self.__get_previously_used_accounts() 386 self._CBOX_user = wx.ComboBox ( 387 self, 388 -1, 389 self.__previously_used_accounts[0], 390 wx.DefaultPosition, 391 wx.Size(150,-1), 392 self.__previously_used_accounts, 393 wx.CB_DROPDOWN 394 ) 395 self.pboxgrid.Add( self._CBOX_user, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 ) 396 397 #PASSWORD TEXT ENTRY 398 label = wx.StaticText( self, -1, _("Password"), wx.DefaultPosition, wx.DefaultSize, 0 ) 399 label.SetForegroundColour(wx.Colour(35, 35, 142)) 400 self.pboxgrid.Add( label, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 ) 401 self.pwdentry = wx.TextCtrl( self, 1, '', wx.DefaultPosition, wx.Size(80,-1), wx.TE_PASSWORD ) 402 # set focus on password entry 403 self.pwdentry.SetFocus() 404 self.pboxgrid.Add( self.pwdentry, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) 405 406 # --debug checkbox 407 label = wx.StaticText(self, -1, _('Options'), wx.DefaultPosition, wx.DefaultSize, 0) 408 label.SetForegroundColour(wx.Colour(35, 35, 142)) 409 self.pboxgrid.Add(label, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) 410 self._CHBOX_debug = wx.CheckBox(self, -1, _('&Debug mode')) 411 self._CHBOX_debug.SetToolTipString(_('Check this to run GNUmed client in debugging mode.')) 412 self.pboxgrid.Add(self._CHBOX_debug, 0, wx.GROW | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5) 413 414 # --slave checkbox 415 label = wx.StaticText(self, -1, '', wx.DefaultPosition, wx.DefaultSize, 0) 416 label.SetForegroundColour(wx.Colour(35, 35, 142)) 417 self.pboxgrid.Add(label, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) 418 self._CHBOX_slave = wx.CheckBox(self, -1, _('Enable &remote control')) 419 self._CHBOX_slave.SetToolTipString(_('Check this to run GNUmed client in slave mode for remote control.')) 420 self.pboxgrid.Add(self._CHBOX_slave, 0, wx.GROW | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5) 421 422 #---------------------------------------------------------------------- 423 #new button code inserted rterry 06Sept02 424 #button order re-arraged to make it consistant with usual dialog format 425 #in most operating systems ie btns ok and cancel are standard and 426 #in that order 427 #ie Order is now help, ok and cancel 428 #The order of creation is the tab order 429 #login-ok button automatically is the default when tabbing (or <enter>) 430 #from password 431 #this eliminates the heavy border when you use the default 432 #?is the default word needed for any other reason? 433 #---------------------------------------------------------------------- 434 self.button_gridsizer = wx.GridSizer(1,3,0,0) 435 #--------------------- 436 #3:create login ok button 437 #--------------------- 438 ID_BUTTON_LOGIN = wx.NewId() 439 button_login_ok = wx.Button(self, ID_BUTTON_LOGIN, _("&Ok"), wx.DefaultPosition, wx.DefaultSize, 0 ) 440 button_login_ok.SetToolTip(wx.ToolTip(_("Proceed with login.")) ) 441 button_login_ok.SetDefault() 442 443 #--------------------- 444 #3:create cancel button 445 #--------------------- 446 ID_BUTTON_CANCEL = wx.NewId() 447 button_cancel = wx.Button(self, ID_BUTTON_CANCEL, _("&Cancel"), wx.DefaultPosition, wx.DefaultSize, 0 ) 448 button_cancel.SetToolTip(wx.ToolTip(_("Cancel Login.")) ) 449 #--------------------- 450 #2:create Help button 451 #--------------------- 452 ID_BUTTON_HELP = wx.NewId() 453 button_help = wx.Button(self, ID_BUTTON_HELP, _("&Help"), wx.DefaultPosition, wx.DefaultSize, 0 ) 454 button_help.SetToolTip(wx.ToolTip(_("Help for login screen"))) 455 #---------------------------- 456 #Add buttons to the gridsizer 457 #---------------------------- 458 self.button_gridsizer.Add (button_help,0,wx.EXPAND|wx.ALL,5) 459 self.button_gridsizer.Add (button_login_ok,0,wx.EXPAND|wx.ALL,5) 460 self.button_gridsizer.Add (button_cancel,0,wx.EXPAND|wx.ALL,5) 461 462 self.paramsboxsizer.Add(self.pboxgrid, 1, wx.GROW|wx.ALL, 10) 463 self.topsizer.Add(self.paramsboxsizer, 1, wx.GROW|wx.ALL, 10) 464 self.topsizer.Add( self.button_gridsizer, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 ) 465 466 self.__load_state() 467 468 self.SetAutoLayout(True) 469 self.SetSizer( self.topsizer) 470 self.topsizer.Fit( self ) 471 if self.isDialog: 472 self.topsizer.SetSizeHints(parent) 473 474 wx.EVT_BUTTON(self, ID_BUTTON_HELP, self.OnHelp) 475 wx.EVT_BUTTON(self, ID_BUTTON_LOGIN, self.__on_login_button_pressed) 476 wx.EVT_BUTTON(self, ID_BUTTON_CANCEL, self.OnCancel)
477 478 #---------------------------------------------------------- 479 # internal helper methods 480 #----------------------------------------------------------
482 483 accounts = gmTools.coalesce ( 484 _cfg.get ( 485 group = u'backend', 486 option = u'logins', 487 source_order = [ 488 (u'explicit', u'extend'), 489 (u'user', u'extend'), 490 (u'workbase', u'extend') 491 ] 492 ), 493 ['any-doc'] 494 ) 495 # FIXME: make unique 496 497 return accounts
498 #----------------------------------------------------
499 - def __get_backend_profiles(self):
500 """Get server profiles from the configuration files. 501 502 1) from system-wide file 503 2) from user file 504 505 Profiles in the user file which have the same name 506 as a profile in the system file will override the 507 system file. 508 """ 509 # find active profiles 510 src_order = [ 511 (u'explicit', u'extend'), 512 (u'system', u'extend'), 513 (u'user', u'extend'), 514 (u'workbase', u'extend') 515 ] 516 517 profile_names = gmTools.coalesce ( 518 _cfg.get(group = u'backend', option = u'profiles', source_order = src_order), 519 [] 520 ) 521 522 # find data for active profiles 523 src_order = [ 524 (u'explicit', u'return'), 525 (u'workbase', u'return'), 526 (u'user', u'return'), 527 (u'system', u'return') 528 ] 529 530 profiles = {} 531 532 for profile_name in profile_names: 533 # FIXME: once the profile has been found always use the corresponding source ! 534 # FIXME: maybe not or else we cannot override parts of the profile 535 profile = cBackendProfile() 536 profile_section = 'profile %s' % profile_name 537 538 profile.name = profile_name 539 profile.host = gmTools.coalesce(_cfg.get(profile_section, u'host', src_order), u'').strip() 540 port = gmTools.coalesce(_cfg.get(profile_section, u'port', src_order), 5432) 541 try: 542 profile.port = int(port) 543 if profile.port < 1024: 544 raise ValueError('refusing to use priviledged port (< 1024)') 545 except ValueError: 546 _log.warning('invalid port definition: [%s], skipping profile [%s]', port, profile_name) 547 continue 548 profile.database = gmTools.coalesce(_cfg.get(profile_section, u'database', src_order), u'').strip() 549 if profile.database == u'': 550 _log.warning('database name not specified, skipping profile [%s]', profile_name) 551 continue 552 profile.encoding = gmTools.coalesce(_cfg.get(profile_section, u'encoding', src_order), u'UTF8') 553 profile.public_db = bool(_cfg.get(profile_section, u'public/open access', src_order)) 554 profile.helpdesk = _cfg.get(profile_section, u'help desk', src_order) 555 556 label = u'%s (%s@%s)' % (profile_name, profile.database, profile.host) 557 profiles[label] = profile 558 559 # sort out profiles with incompatible database versions if not --debug 560 # NOTE: this essentially hardcodes the database name in production ... 561 if not (_cfg.get(option = 'debug') or current_db_name.endswith('_devel')): 562 profiles2remove = [] 563 for label in profiles: 564 if profiles[label].database != current_db_name: 565 profiles2remove.append(label) 566 for label in profiles2remove: 567 del profiles[label] 568 569 if len(profiles) == 0: 570 host = u'salaam.homeunix.com' 571 label = u'public GNUmed database (%s@%s)' % (current_db_name, host) 572 profiles[label] = cBackendProfile() 573 profiles[label].name = label 574 profiles[label].host = host 575 profiles[label].port = 5432 576 profiles[label].database = current_db_name 577 profiles[label].encoding = u'UTF8' 578 profiles[label].public_db = True 579 profiles[label].helpdesk = u'http://wiki.gnumed.de' 580 581 return profiles
582 #----------------------------------------------------------
583 - def __load_state(self):
584 585 src_order = [ 586 (u'explicit', u'return'), 587 (u'user', u'return'), 588 ] 589 590 self._CBOX_user.SetValue ( 591 gmTools.coalesce ( 592 _cfg.get(u'preferences', u'login', src_order), 593 self.__previously_used_accounts[0] 594 ) 595 ) 596 597 last_used_profile_label = _cfg.get(u'preferences', u'profile', src_order) 598 if last_used_profile_label in self.__backend_profiles.keys(): 599 self._CBOX_profile.SetValue(last_used_profile_label) 600 else: 601 self._CBOX_profile.SetValue(self.__backend_profiles.keys()[0]) 602 603 self._CHBOX_debug.SetValue(_cfg.get(option = 'debug')) 604 self._CHBOX_slave.SetValue(_cfg.get(option = 'slave'))
605 #----------------------------------------------------
606 - def save_state(self):
607 """Save parameter settings to standard configuration file""" 608 prefs_name = _cfg.get(option = 'user_preferences_file') 609 _log.debug(u'saving login preferences in [%s]', prefs_name) 610 611 gmCfg2.set_option_in_INI_file ( 612 filename = prefs_name, 613 group = 'preferences', 614 option = 'login', 615 value = self._CBOX_user.GetValue() 616 ) 617 618 gmCfg2.set_option_in_INI_file ( 619 filename = prefs_name, 620 group = 'preferences', 621 option = 'profile', 622 value = self._CBOX_profile.GetValue() 623 )
624 ############################################################################# 625 # Retrieve current settings from user interface widgets 626 #############################################################################
627 - def GetLoginInfo(self):
628 """convenience function for compatibility with gmLoginInfo.LoginInfo""" 629 if not self.cancelled: 630 # FIXME: do not assume conf file is latin1 ! 631 #profile = self.__backend_profiles[self._CBOX_profile.GetValue().encode('latin1').strip()] 632 profile = self.__backend_profiles[self._CBOX_profile.GetValue().encode('utf8').strip()] 633 _log.debug(u'backend profile "%s" selected', profile.name) 634 _log.debug(u' details: <%s> on %s@%s:%s (%s, %s)', 635 self._CBOX_user.GetValue(), 636 profile.database, 637 profile.host, 638 profile.port, 639 profile.encoding, 640 gmTools.bool2subst(profile.public_db, u'public', u'private') 641 ) 642 _log.debug(u' helpdesk: "%s"', profile.helpdesk) 643 login = gmLoginInfo.LoginInfo ( 644 user = self._CBOX_user.GetValue(), 645 password = self.pwdentry.GetValue(), 646 host = profile.host, 647 database = profile.database, 648 port = profile.port 649 ) 650 login.public_db = profile.public_db 651 login.helpdesk = profile.helpdesk 652 return login 653 654 return None
655 #---------------------------- 656 # event handlers 657 #----------------------------
658 - def OnHelp(self, event):
659 praxis = gmSurgery.gmCurrentPractice() 660 wx.MessageBox(_( 661 """GNUmed main login screen 662 663 USER: 664 name of the GNUmed user 665 PASSWORD 666 password for this user 667 668 button OK: 669 proceed with login 670 button OPTIONS: 671 set advanced options 672 button CANCEL: 673 abort login and quit GNUmed client 674 button HELP: 675 this help screen 676 677 For assistance on using GNUmed please contact: 678 %s""") % praxis.helpdesk)
679 680 #----------------------------
681 - def __on_login_button_pressed(self, event):
682 683 root_logger = logging.getLogger() 684 if self._CHBOX_debug.GetValue(): 685 _log.info('debug mode enabled') 686 _cfg.set_option(option = 'debug', value = True) 687 root_logger.setLevel(logging.DEBUG) 688 else: 689 _log.info('debug mode disabled') 690 _cfg.set_option(option = 'debug', value = False) 691 if _cfg.get(option = '--quiet', source_order = [('cli', 'return')]): 692 root_logger.setLevel(logging.ERROR) 693 else: 694 root_logger.setLevel(logging.WARNING) 695 696 if self._CHBOX_slave.GetValue(): 697 _log.info('slave mode enabled') 698 _cfg.set_option(option = 'slave', value = True) 699 else: 700 _log.info('slave mode disabled') 701 _cfg.set_option(option = 'slave', value = False) 702 703 self.backend_profile = self.__backend_profiles[self._CBOX_profile.GetValue().encode('latin1').strip()] 704 # self.user = self._CBOX_user.GetValue().strip() 705 # self.password = self.GetPassword() 706 self.cancelled = False 707 self.parent.Close()
708 #----------------------------
709 - def OnCancel(self, event):
710 self.cancelled = True 711 self.parent.Close()
712 713 #================================================================ 714 # main 715 #---------------------------------------------------------------- 716 if __name__ == "__main__": 717 718 if len(sys.argv) < 2: 719 sys.exit() 720 721 if sys.argv[1] != 'test': 722 sys.exit() 723 724 # we don't have tests yet 725 sys.exit() 726 727 from Gnumed.pycommon import gmI18N 728 729 logging.basicConfig(level = logging.DEBUG) 730 731 gmI18N.activate_locale() 732 gmI18N.install_domain(domain='gnumed') 733 #----------------------------------------------- 734 #-----------------------------------------------
735 - def test():
736 app = wx.PyWidgetTester(size = (300,400)) 737 #show the login panel in a main window 738 # app.SetWidget(cLoginPanel, -1) 739 #and pop the login dialog up modally 740 dlg = cLoginDialog(None, -1) #, png_bitmap = 'bitmaps/gnumedlogo.png') 741 dlg.ShowModal() 742 #demonstration how to access the login dialog values 743 lp = dlg.panel.GetLoginInfo() 744 if lp is None: 745 wx.MessageBox(_("Dialog was cancelled by user")) 746 else: 747 wx.MessageBox(_("You tried to log in as [%s] with password [%s].\nHost:%s, DB: %s, Port: %s") % (lp.GetUser(),lp.GetPassword(),lp.GetHost(),lp.GetDatabase(),lp.GetPort())) 748 dlg.Destroy()
749 # app.MainLoop() 750 751 #================================================================ 752