| Trees | Indices | Help |
|
|---|
|
|
1 """GNUmed authentication widgets.
2
3 This module contains widgets and GUI
4 functions for authenticating users.
5 """
6 #================================================================
7 # $Source: /cvsroot/gnumed/gnumed/gnumed/client/wxpython/gmAuthWidgets.py,v $
8 # $Id: gmAuthWidgets.py,v 1.45 2009/11/06 15:16:21 ncq Exp $
9 __version__ = "$Revision: 1.45 $"
10 __author__ = "karsten.hilbert@gmx.net, H.Herb, H.Berger, R.Terry"
11 __license__ = "GPL (details at http://www.gnu.org)"
12
13
14 # stdlib
15 import sys, os.path, cPickle, zlib, logging
16
17
18 # 3rd party
19 import wx
20
21
22 # GNUmed
23 if __name__ == '__main__':
24 sys.path.insert(0, '../../')
25 from Gnumed.pycommon import gmLoginInfo, gmPG2, gmBackendListener, gmTools, gmCfg2, gmI18N
26 from Gnumed.business import gmSurgery
27 from Gnumed.wxpython import gmGuiHelpers, gmExceptionHandlingWidgets
28
29
30 _log = logging.getLogger('gm.ui')
31 _log.info(__version__)
32 _cfg = gmCfg2.gmCfgData()
33
34 try:
35 _('dummy-no-need-to-translate-but-make-epydoc-happy')
36 except NameError:
37 _ = lambda x:x
38
39
40 msg_generic = _("""
41 GNUmed database version mismatch.
42
43 This database version cannot be used with this client:
44
45 client version: %s
46 database version detected: %s
47 database version needed: %s
48
49 Currently connected to database:
50
51 host: %s
52 database: %s
53 user: %s
54 """)
55
56 msg_time_skew_fail = _("""\
57 The server and client clocks are off
58 by more than %s minutes !
59
60 You must fix the time settings before
61 you can use this database with this
62 client.
63
64 You may have to contact your
65 administrator for help.""")
66
67 msg_time_skew_warn = _("""\
68 The server and client clocks are off
69 by more than %s minutes !
70
71 You should fix the time settings.
72 Otherwise clinical data may appear to
73 have been entered at the wrong time.
74
75 You may have to contact your
76 administrator for help.""")
77
78 msg_insanity = _("""
79 There is a serious problem with the database settings:
80
81 %s
82
83 You may have to contact your administrator for help.""")
84
85 msg_fail = _("""
86 You must connect to a different database in order
87 to use the GNUmed client. You may have to contact
88 your administrator for help.""")
89
90 msg_override = _("""
91 The client will, however, continue to start up because
92 you are running a development/test version of GNUmed.
93
94 There may be schema related errors. Please report and/or
95 fix them. Do not rely on this database to work properly
96 in all cases !""")
97
98 #================================================================
99 # convenience functions
100 #----------------------------------------------------------------
102 """Display the login dialog and try to log into the backend.
103
104 - up to max_attempts times
105 - returns True/False
106 """
107 # force programmer to set a valid expected_version
108 expected_hash = gmPG2.known_schema_hashes[expected_version]
109 client_version = _cfg.get(option = u'client_version')
110 global current_db_name
111 current_db_name = u'gnumed_%s' % expected_version
112
113 attempt = 0
114
115 dlg = cLoginDialog(None, -1, client_version = client_version)
116 dlg.Centre(wx.BOTH)
117
118 while attempt < max_attempts:
119
120 _log.debug('login attempt %s of %s', (attempt+1), max_attempts)
121
122 connected = False
123
124 dlg.ShowModal()
125 login = dlg.panel.GetLoginInfo()
126 if login is None:
127 _log.info("user cancelled login dialog")
128 break
129
130 # try getting a connection to verify the DSN works
131 dsn = gmPG2.make_psycopg2_dsn (
132 database = login.database,
133 host = login.host,
134 port = login.port,
135 user = login.user,
136 password = login.password
137 )
138 try:
139 conn = gmPG2.get_raw_connection(dsn = dsn, verbose = True, readonly = True)
140 connected = True
141
142 except gmPG2.cAuthenticationError, e:
143 attempt += 1
144 _log.error(u"login attempt failed: %s", e)
145 if attempt < max_attempts:
146 gmGuiHelpers.gm_show_error (_(
147 "Unable to connect to database:\n\n"
148 "%s\n\n"
149 "Please retry with proper credentials or cancel.\n"
150 "\n"
151 'You may also need to check the PostgreSQL client\n'
152 'authentication configuration in pg_hba.conf. For\n'
153 'details see:\n'
154 '\n'
155 'wiki.gnumed.de/bin/view/Gnumed/ConfigurePostgreSQL'
156 ) % e,
157 _('Connecting to backend')
158 )
159 del e
160 continue
161
162 except gmPG2.dbapi.OperationalError, e:
163 _log.error(u"login attempt failed: %s", e)
164 gmGuiHelpers.gm_show_error (_(
165 "Unable to connect to database:\n\n"
166 "%s\n\n"
167 "Please retry another backend / user / password combination !\n"
168 ) % gmPG2.extract_msg_from_pg_exception(e),
169 _('Connecting to backend')
170 )
171 del e
172 continue
173
174 # connect was successful
175 gmPG2.set_default_login(login = login)
176 gmPG2.set_default_client_encoding(encoding = dlg.panel.backend_profile.encoding)
177
178 compatible = gmPG2.database_schema_compatible(version = expected_version)
179 if compatible or not require_version:
180 dlg.panel.save_state()
181
182 if not compatible:
183 connected_db_version = gmPG2.get_schema_version()
184 msg = msg_generic % (
185 client_version,
186 connected_db_version,
187 expected_version,
188 gmTools.coalesce(login.host, '<localhost>'),
189 login.database,
190 login.user
191 )
192 if require_version:
193 gmGuiHelpers.gm_show_error(msg + msg_fail, _('Verifying database version'))
194 continue
195 gmGuiHelpers.gm_show_info(msg + msg_override, _('Verifying database version'))
196
197 # FIXME: make configurable
198 max_skew = 1 # minutes
199 if _cfg.get(option = 'debug'):
200 max_skew = 10
201 if not gmPG2.sanity_check_time_skew(tolerance = (max_skew * 60)):
202 if _cfg.get(option = 'debug'):
203 gmGuiHelpers.gm_show_warning(msg_time_skew_warn % max_skew, _('Verifying database settings'))
204 else:
205 gmGuiHelpers.gm_show_error(msg_time_skew_fail % max_skew, _('Verifying database settings'))
206 continue
207
208 sanity_level, message = gmPG2.sanity_check_database_settings()
209 if sanity_level != 0:
210 gmGuiHelpers.gm_show_error((msg_insanity % message), _('Verifying database settings'))
211 if sanity_level == 2:
212 continue
213
214 gmExceptionHandlingWidgets.set_is_public_database(login.public_db)
215 gmExceptionHandlingWidgets.set_helpdesk(login.helpdesk)
216
217 listener = gmBackendListener.gmBackendListener(conn = conn)
218 break
219
220 dlg.Destroy()
221
222 return connected
223 #================================================================
225 if procedure is None:
226 procedure = _('<restricted procedure>')
227
228 # 1) get password for gm-dbo
229 if dbo_password is None:
230 pwd_gm_dbo = wx.GetPasswordFromUser (
231 message = _("""
232 [%s]
233
234 This is a restricted procedure. We need the
235 password for the GNUmed database owner.
236
237 Please enter the password for <gm-dbo>:""") % procedure,
238 caption = procedure
239 )
240 if pwd_gm_dbo == '':
241 return None
242 else:
243 pwd_gm_dbo = dbo_password
244
245 # 2) connect as gm-dbo
246 login = gmPG2.get_default_login()
247 dsn = gmPG2.make_psycopg2_dsn(database=login.database, host=login.host, port=login.port, user='gm-dbo', password=pwd_gm_dbo)
248 try:
249 conn = gmPG2.get_connection(dsn=dsn, readonly=False, verbose=True, pooled=False)
250 except:
251 _log.exception('cannot connect')
252 gmGuiHelpers.gm_show_error (
253 aMessage = _('Cannot connect as the GNUmed database owner <gm-dbo>.'),
254 aTitle = procedure
255 )
256 return None
257
258 return conn
259 #================================================================
262 #================================================================
264 """cLoginDialog - window holding cLoginPanel"""
265
266 icon_serpent='x\xdae\x8f\xb1\x0e\x83 \x10\x86w\x9f\xe2\x92\x1blb\xf2\x07\x96\xeaH:0\xd6\
267 \xc1\x85\xd5\x98N5\xa5\xef?\xf5N\xd0\x8a\xdcA\xc2\xf7qw\x84\xdb\xfa\xb5\xcd\
268 \xd4\xda;\xc9\x1a\xc8\xb6\xcd<\xb5\xa0\x85\x1e\xeb\xbc\xbc7b!\xf6\xdeHl\x1c\
269 \x94\x073\xec<*\xf7\xbe\xf7\x99\x9d\xb21~\xe7.\xf5\x1f\x1c\xd3\xbdVlL\xc2\
270 \xcf\xf8ye\xd0\x00\x90\x0etH \x84\x80B\xaa\x8a\x88\x85\xc4(U\x9d$\xfeR;\xc5J\
271 \xa6\x01\xbbt9\xceR\xc8\x81e_$\x98\xb9\x9c\xa9\x8d,y\xa9t\xc8\xcf\x152\xe0x\
272 \xe9$\xf5\x07\x95\x0cD\x95t:\xb1\x92\xae\x9cI\xa8~\x84\x1f\xe0\xa3ec'
273
275 wx.Dialog.__init__(self, parent, id, title)
276 self.panel = cLoginPanel(self, -1, isDialog=1, client_version = client_version)
277 self.Fit() # needed for Windoze.
278 self.Centre()
279
280 # set window icon
281 icon_bmp_data = wx.BitmapFromXPMData(cPickle.loads(zlib.decompress(self.icon_serpent)))
282 icon = wx.EmptyIcon()
283 icon.CopyFromBitmap(icon_bmp_data)
284 self.SetIcon(icon)
285 #================================================================
287 """GUI panel class that interactively gets Postgres login parameters.
288
289 It features combo boxes which "remember" any number of
290 previously entered settings.
291 """
292 - def __init__(self, parent, id,
293 pos = wx.DefaultPosition, size = wx.DefaultSize, style = wx.TAB_TRAVERSAL,
294 isDialog = 0, client_version = u'*** unknown ***'):
295 """Create login panel.
296
297 isDialog: if this panel is the main panel of a dialog, the panel will
298 resize the dialog automatically to display everything neatly
299 if isDialog is set to True
300 """
301 wx.Panel.__init__(self, parent, id, pos, size, style)
302 self.parent = parent
303
304 #True if dialog was cancelled by user
305 #if the dialog is closed manually, login should be cancelled
306 self.cancelled = True
307
308 # True if this panel is displayed within a dialog (will resize the dialog automatically then)
309 self.isDialog = isDialog
310
311 self.topsizer = wx.BoxSizer(wx.VERTICAL)
312
313 # find bitmap
314 paths = gmTools.gmPaths(app_name = u'gnumed', wx = wx)
315 bitmap = os.path.join(paths.system_app_data_dir, 'bitmaps', 'gnumedlogo.png')
316 try:
317 png = wx.Image(bitmap, wx.BITMAP_TYPE_PNG).ConvertToBitmap()
318 bmp = wx.StaticBitmap(self, -1, png, wx.Point(10, 10), wx.Size(png.GetWidth(), png.GetHeight()))
319 self.topsizer.Add (
320 bmp,
321 proportion = 0,
322 flag = wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL,
323 border = 10
324 )
325 except:
326 self.topsizer.Add (
327 wx.StaticText (
328 self,
329 -1,
330 label = _("Cannot find image") + bitmap,
331 style = wx.ALIGN_CENTRE
332 ),
333 proportion = 0,
334 flag = wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL,
335 border = 10
336 )
337
338 paramsbox_caption = _('"%s" (version %s)') % (gmSurgery.gmCurrentPractice().active_workplace, client_version)
339
340 # FIXME: why doesn't this align in the centre ?
341 self.paramsbox = wx.StaticBox( self, -1, paramsbox_caption, style = wx.ALIGN_CENTRE_HORIZONTAL)
342 self.paramsboxsizer = wx.StaticBoxSizer( self.paramsbox, wx.VERTICAL )
343 self.paramsbox.SetForegroundColour(wx.Colour(35, 35, 142))
344 self.paramsbox.SetFont(wx.Font(
345 pointSize = 12,
346 family = wx.SWISS,
347 style = wx.NORMAL,
348 weight = wx.BOLD,
349 underline = False
350 ))
351 self.pboxgrid = wx.FlexGridSizer(5, 2, 5, 5)
352 self.pboxgrid.AddGrowableCol(1)
353
354 # PROFILE COMBO
355 label = wx.StaticText( self, -1, _('Log into'), wx.DefaultPosition, wx.DefaultSize, 0)
356 label.SetForegroundColour(wx.Colour(35, 35, 142))
357 self.pboxgrid.Add(label, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)
358 self.__backend_profiles = self.__get_backend_profiles()
359 self._CBOX_profile = wx.ComboBox (
360 self,
361 -1,
362 self.__backend_profiles.keys()[0],
363 wx.DefaultPosition,
364 size = wx.Size(150,-1),
365 choices = self.__backend_profiles.keys(),
366 style = wx.CB_READONLY
367 )
368 self.pboxgrid.Add (self._CBOX_profile, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
369
370 # USER NAME COMBO
371 label = wx.StaticText( self, -1, _("Username"), wx.DefaultPosition, wx.DefaultSize, 0 )
372 label.SetForegroundColour(wx.Colour(35, 35, 142))
373 self.pboxgrid.Add(label, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
374 self.__previously_used_accounts = self.__get_previously_used_accounts()
375 self._CBOX_user = wx.ComboBox (
376 self,
377 -1,
378 self.__previously_used_accounts[0],
379 wx.DefaultPosition,
380 wx.Size(150,-1),
381 self.__previously_used_accounts,
382 wx.CB_DROPDOWN
383 )
384 self.pboxgrid.Add( self._CBOX_user, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
385
386 #PASSWORD TEXT ENTRY
387 label = wx.StaticText( self, -1, _("Password"), wx.DefaultPosition, wx.DefaultSize, 0 )
388 label.SetForegroundColour(wx.Colour(35, 35, 142))
389 self.pboxgrid.Add( label, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
390 self.pwdentry = wx.TextCtrl( self, 1, '', wx.DefaultPosition, wx.Size(80,-1), wx.TE_PASSWORD )
391 # set focus on password entry
392 self.pwdentry.SetFocus()
393 self.pboxgrid.Add( self.pwdentry, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
394
395 # --debug checkbox
396 label = wx.StaticText(self, -1, _('Options'), wx.DefaultPosition, wx.DefaultSize, 0)
397 label.SetForegroundColour(wx.Colour(35, 35, 142))
398 self.pboxgrid.Add(label, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
399 self._CHBOX_debug = wx.CheckBox(self, -1, _('&Debug mode'))
400 self._CHBOX_debug.SetToolTipString(_('Check this to run GNUmed client in debugging mode.'))
401 self.pboxgrid.Add(self._CHBOX_debug, 0, wx.GROW | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)
402
403 # --slave checkbox
404 label = wx.StaticText(self, -1, '', wx.DefaultPosition, wx.DefaultSize, 0)
405 label.SetForegroundColour(wx.Colour(35, 35, 142))
406 self.pboxgrid.Add(label, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
407 self._CHBOX_slave = wx.CheckBox(self, -1, _('Enable &remote control'))
408 self._CHBOX_slave.SetToolTipString(_('Check this to run GNUmed client in slave mode for remote control.'))
409 self.pboxgrid.Add(self._CHBOX_slave, 0, wx.GROW | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)
410
411 #----------------------------------------------------------------------
412 #new button code inserted rterry 06Sept02
413 #button order re-arraged to make it consistant with usual dialog format
414 #in most operating systems ie btns ok and cancel are standard and
415 #in that order
416 #ie Order is now help, ok and cancel
417 #The order of creation is the tab order
418 #login-ok button automatically is the default when tabbing (or <enter>)
419 #from password
420 #this eliminates the heavy border when you use the default
421 #?is the default word needed for any other reason?
422 #----------------------------------------------------------------------
423 self.button_gridsizer = wx.GridSizer(1,3,0,0)
424 #---------------------
425 #3:create login ok button
426 #---------------------
427 ID_BUTTON_LOGIN = wx.NewId()
428 button_login_ok = wx.Button(self, ID_BUTTON_LOGIN, _("&Ok"), wx.DefaultPosition, wx.DefaultSize, 0 )
429 button_login_ok.SetToolTip(wx.ToolTip(_("Proceed with login.")) )
430 button_login_ok.SetDefault()
431
432 #---------------------
433 #3:create cancel button
434 #---------------------
435 ID_BUTTON_CANCEL = wx.NewId()
436 button_cancel = wx.Button(self, ID_BUTTON_CANCEL, _("&Cancel"), wx.DefaultPosition, wx.DefaultSize, 0 )
437 button_cancel.SetToolTip(wx.ToolTip(_("Cancel Login.")) )
438 #---------------------
439 #2:create Help button
440 #---------------------
441 ID_BUTTON_HELP = wx.NewId()
442 button_help = wx.Button(self, ID_BUTTON_HELP, _("&Help"), wx.DefaultPosition, wx.DefaultSize, 0 )
443 button_help.SetToolTip(wx.ToolTip(_("Help for login screen")))
444 #----------------------------
445 #Add buttons to the gridsizer
446 #----------------------------
447 self.button_gridsizer.Add (button_help,0,wx.EXPAND|wx.ALL,5)
448 self.button_gridsizer.Add (button_login_ok,0,wx.EXPAND|wx.ALL,5)
449 self.button_gridsizer.Add (button_cancel,0,wx.EXPAND|wx.ALL,5)
450
451 self.paramsboxsizer.Add(self.pboxgrid, 1, wx.GROW|wx.ALL, 10)
452 self.topsizer.Add(self.paramsboxsizer, 1, wx.GROW|wx.ALL, 10)
453 self.topsizer.Add( self.button_gridsizer, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
454
455 self.__load_state()
456
457 self.SetAutoLayout(True)
458 self.SetSizer( self.topsizer)
459 self.topsizer.Fit( self )
460 if self.isDialog:
461 self.topsizer.SetSizeHints(parent)
462
463 wx.EVT_BUTTON(self, ID_BUTTON_HELP, self.OnHelp)
464 wx.EVT_BUTTON(self, ID_BUTTON_LOGIN, self.__on_login_button_pressed)
465 wx.EVT_BUTTON(self, ID_BUTTON_CANCEL, self.OnCancel)
466
467 #----------------------------------------------------------
468 # internal helper methods
469 #----------------------------------------------------------
471
472 accounts = gmTools.coalesce (
473 _cfg.get (
474 group = u'backend',
475 option = u'logins',
476 source_order = [
477 (u'explicit', u'extend'),
478 (u'user', u'extend'),
479 (u'workbase', u'extend')
480 ]
481 ),
482 ['any-doc']
483 )
484 # FIXME: make unique
485
486 return accounts
487 #----------------------------------------------------
489 """Get server profiles from the configuration files.
490
491 1) from system-wide file
492 2) from user file
493
494 Profiles in the user file which have the same name
495 as a profile in the system file will override the
496 system file.
497 """
498 # find active profiles
499 src_order = [
500 (u'explicit', u'extend'),
501 (u'system', u'extend'),
502 (u'user', u'extend'),
503 (u'workbase', u'extend')
504 ]
505
506 profile_names = gmTools.coalesce (
507 _cfg.get(group = u'backend', option = u'profiles', source_order = src_order),
508 []
509 )
510
511 # find data for active profiles
512 src_order = [
513 (u'explicit', u'return'),
514 (u'workbase', u'return'),
515 (u'user', u'return'),
516 (u'system', u'return')
517 ]
518
519 profiles = {}
520
521 for profile_name in profile_names:
522 # FIXME: once the profile has been found always use the corresponding source !
523 # FIXME: maybe not or else we cannot override parts of the profile
524 profile = cBackendProfile()
525 profile_section = 'profile %s' % profile_name
526
527 profile.name = profile_name
528 profile.host = gmTools.coalesce(_cfg.get(profile_section, u'host', src_order), u'').strip()
529 port = gmTools.coalesce(_cfg.get(profile_section, u'port', src_order), 5432)
530 try:
531 profile.port = int(port)
532 if profile.port < 1024:
533 raise ValueError('refusing to use priviledged port (< 1024)')
534 except ValueError:
535 _log.warning('invalid port definition: [%s], skipping profile [%s]', port, profile_name)
536 continue
537 profile.database = gmTools.coalesce(_cfg.get(profile_section, u'database', src_order), u'').strip()
538 if profile.database == u'':
539 _log.warning('database name not specified, skipping profile [%s]', profile_name)
540 continue
541 profile.encoding = gmTools.coalesce(_cfg.get(profile_section, u'encoding', src_order), u'UTF8')
542 profile.public_db = bool(_cfg.get(profile_section, u'public/open access', src_order))
543 profile.helpdesk = _cfg.get(profile_section, u'help desk', src_order)
544
545 label = u'%s (%s@%s)' % (profile_name, profile.database, profile.host)
546 profiles[label] = profile
547
548 # sort out profiles with incompatible database versions if not --debug
549 # NOTE: this essentially hardcodes the database name in production ...
550 if not (_cfg.get(option = 'debug') or current_db_name.endswith('_devel')):
551 profiles2remove = []
552 for label in profiles:
553 if profiles[label].database != current_db_name:
554 profiles2remove.append(label)
555 for label in profiles2remove:
556 del profiles[label]
557
558 if len(profiles) == 0:
559 host = u'salaam.homeunix.com'
560 label = u'public GNUmed database (%s@%s)' % (current_db_name, host)
561 profiles[label] = cBackendProfile()
562 profiles[label].name = label
563 profiles[label].host = host
564 profiles[label].port = 5432
565 profiles[label].database = current_db_name
566 profiles[label].encoding = u'UTF8'
567 profiles[label].public_db = True
568 profiles[label].helpdesk = u'http://wiki.gnumed.de'
569
570 return profiles
571 #----------------------------------------------------------
573
574 src_order = [
575 (u'explicit', u'return'),
576 (u'user', u'return'),
577 ]
578
579 self._CBOX_user.SetValue (
580 gmTools.coalesce (
581 _cfg.get(u'preferences', u'login', src_order),
582 self.__previously_used_accounts[0]
583 )
584 )
585
586 last_used_profile_label = _cfg.get(u'preferences', u'profile', src_order)
587 if last_used_profile_label in self.__backend_profiles.keys():
588 self._CBOX_profile.SetValue(last_used_profile_label)
589 else:
590 self._CBOX_profile.SetValue(self.__backend_profiles.keys()[0])
591
592 self._CHBOX_debug.SetValue(_cfg.get(option = 'debug'))
593 self._CHBOX_slave.SetValue(_cfg.get(option = 'slave'))
594 #----------------------------------------------------
596 """Save parameter settings to standard configuration file"""
597 prefs_name = _cfg.get(option = 'user_preferences_file')
598 _log.debug(u'saving login preferences in [%s]', prefs_name)
599
600 gmCfg2.set_option_in_INI_file (
601 filename = prefs_name,
602 group = 'preferences',
603 option = 'login',
604 value = self._CBOX_user.GetValue()
605 )
606
607 gmCfg2.set_option_in_INI_file (
608 filename = prefs_name,
609 group = 'preferences',
610 option = 'profile',
611 value = self._CBOX_profile.GetValue()
612 )
613 #############################################################################
614 # Retrieve current settings from user interface widgets
615 #############################################################################
617 """convenience function for compatibility with gmLoginInfo.LoginInfo"""
618 if not self.cancelled:
619 # FIXME: do not assume conf file is latin1 !
620 #profile = self.__backend_profiles[self._CBOX_profile.GetValue().encode('latin1').strip()]
621 profile = self.__backend_profiles[self._CBOX_profile.GetValue().encode('utf8').strip()]
622 _log.debug(u'backend profile "%s" selected', profile.name)
623 _log.debug(u' details: <%s> on %s@%s:%s (%s, %s)',
624 self._CBOX_user.GetValue(),
625 profile.database,
626 profile.host,
627 profile.port,
628 profile.encoding,
629 gmTools.bool2subst(profile.public_db, u'public', u'private')
630 )
631 _log.debug(u' helpdesk: "%s"', profile.helpdesk)
632 login = gmLoginInfo.LoginInfo (
633 user = self._CBOX_user.GetValue(),
634 password = self.pwdentry.GetValue(),
635 host = profile.host,
636 database = profile.database,
637 port = profile.port
638 )
639 login.public_db = profile.public_db
640 login.helpdesk = profile.helpdesk
641 return login
642
643 return None
644 #----------------------------
645 # event handlers
646 #----------------------------
648 praxis = gmSurgery.gmCurrentPractice()
649 wx.MessageBox(_(
650 """GNUmed main login screen
651
652 USER:
653 name of the GNUmed user
654 PASSWORD
655 password for this user
656
657 button OK:
658 proceed with login
659 button OPTIONS:
660 set advanced options
661 button CANCEL:
662 abort login and quit GNUmed client
663 button HELP:
664 this help screen
665
666 For assistance on using GNUmed please contact:
667 %s""") % praxis.helpdesk)
668
669 #----------------------------
697 #----------------------------
701
702 #================================================================
703 # main
704 #----------------------------------------------------------------
705 if __name__ == "__main__":
706
707 from Gnumed.pycommon import gmI18N
708
709 logging.basicConfig(level = logging.DEBUG)
710
711 gmI18N.activate_locale()
712 gmI18N.install_domain(domain='gnumed')
713 #-----------------------------------------------
714 #-----------------------------------------------
716 app = wx.PyWidgetTester(size = (300,400))
717 #show the login panel in a main window
718 # app.SetWidget(cLoginPanel, -1)
719 #and pop the login dialog up modally
720 dlg = cLoginDialog(None, -1) #, png_bitmap = 'bitmaps/gnumedlogo.png')
721 dlg.ShowModal()
722 #demonstration how to access the login dialog values
723 lp = dlg.panel.GetLoginInfo()
724 if lp is None:
725 wx.MessageBox(_("Dialog was cancelled by user"))
726 else:
727 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()))
728 dlg.Destroy()
729 # app.MainLoop()
730 #-----------------------------------------------
731 if len(sys.argv) > 1 and sys.argv[1] == 'test':
732 print "no regression tests yet"
733
734 #================================================================
735 # $Log: gmAuthWidgets.py,v $
736 # Revision 1.45 2009/11/06 15:16:21 ncq
737 # - add missing dot
738 #
739 # Revision 1.44 2009/10/20 10:25:10 ncq
740 # - try not to log previous exception instances
741 #
742 # Revision 1.43 2009/09/23 14:33:14 ncq
743 # - improved failed-auth message
744 #
745 # Revision 1.42 2009/07/02 20:50:04 ncq
746 # - cleanup
747 #
748 # Revision 1.41 2009/07/01 17:06:33 ncq
749 # - improved wording
750 #
751 # Revision 1.40 2009/06/11 13:04:13 ncq
752 # - cleanup
753 #
754 # Revision 1.39 2009/06/11 11:07:57 ncq
755 # - properly display localhost
756 #
757 # Revision 1.38 2009/04/14 11:02:20 ncq
758 # - if not debugging and not in development sort out database
759 # profiles with incompatible names, this essentially hardcodes
760 # the database name for the first time
761 #
762 # Revision 1.37 2009/04/03 10:40:17 ncq
763 # - calculate current db name from expected version
764 #
765 # Revision 1.36 2009/04/03 09:38:20 ncq
766 # - bump db version
767 #
768 # Revision 1.35 2009/02/05 13:03:08 ncq
769 # - cleanup
770 #
771 # Revision 1.34 2009/01/15 11:35:41 ncq
772 # - cleanup
773 #
774 # Revision 1.33 2008/12/25 17:46:09 ncq
775 # - better logging
776 # - work around PG unknown initial encoding problem
777 #
778 # Revision 1.32 2008/11/20 18:48:15 ncq
779 # - add default help desk to builtin default backend profile
780 #
781 # Revision 1.31 2008/10/22 12:13:09 ncq
782 # - bump db version
783 #
784 # Revision 1.30 2008/10/12 16:06:07 ncq
785 # - make profile label show db@host
786 # - log profile used
787 #
788 # Revision 1.29 2008/09/09 20:18:51 ncq
789 # - default to any-doc if no previous logins found
790 #
791 # Revision 1.28 2008/08/31 16:47:48 ncq
792 # - proper policy when retrieving previous logins
793 #
794 # Revision 1.27 2008/08/31 16:34:12 ncq
795 # - properly set src_order and policy when retrieving profile *data*
796 #
797 # Revision 1.26 2008/08/31 16:15:02 ncq
798 # - use "extend" policy when retrieving backend profiles
799 #
800 # Revision 1.25 2008/07/30 12:50:34 ncq
801 # - cleanup
802 #
803 # Revision 1.24 2008/07/16 11:11:10 ncq
804 # - set_helpdesk (no more _database_)
805 #
806 # Revision 1.23 2008/07/10 20:52:21 ncq
807 # - better to call path detection with app_name and wx
808 #
809 # Revision 1.22 2008/07/07 11:35:19 ncq
810 # - keyboard shortcuts for check boxes
811 #
812 # Revision 1.21 2008/05/28 21:26:40 ncq
813 # - gracefully handle OperationalErrors such as "server not available"
814 #
815 # Revision 1.20 2008/05/13 14:10:35 ncq
816 # - be more permissive in time skew check
817 # - handle per-profile public-db/helpdesk options
818 #
819 # Revision 1.19 2008/04/16 20:39:39 ncq
820 # - working versions of the wxGlade code and use it, too
821 # - show client version in login dialog
822 #
823 # Revision 1.18 2008/03/20 15:30:21 ncq
824 # - use gmPG2.sanity_check_time_skew()
825 #
826 # Revision 1.17 2008/03/11 17:00:49 ncq
827 # - explicitely request readonly raw connection
828 #
829 # Revision 1.16 2008/03/06 18:29:29 ncq
830 # - standard lib logging only
831 #
832 # Revision 1.15 2008/03/05 22:26:52 ncq
833 # - spelling
834 #
835 # Revision 1.14 2008/02/25 17:33:16 ncq
836 # - use improved db sanity checks
837 #
838 # Revision 1.13 2008/01/30 14:07:02 ncq
839 # - protect against faulty backend profile in preferences
840 #
841 # Revision 1.12 2008/01/27 21:13:17 ncq
842 # - no more gmCfg
843 #
844 # Revision 1.11 2008/01/14 20:33:06 ncq
845 # - cleanup
846 # - properly detect connection errors
847 #
848 # Revision 1.10 2008/01/13 01:16:52 ncq
849 # - log DSN on any connect errors
850 #
851 # Revision 1.9 2008/01/07 19:51:54 ncq
852 # - bump db version
853 # - we still need gmCfg
854 #
855 # Revision 1.8 2007/12/26 23:22:27 ncq
856 # - fix invalid variable access
857 #
858 # Revision 1.7 2007/12/26 22:44:31 ncq
859 # - missing import of logging
860 # - use std lib logger
861 # - cleanup
862 #
863 # Revision 1.6 2007/12/26 22:01:25 shilbert
864 # - cleanup
865 #
866 # Revision 1.5 2007/12/23 22:02:56 ncq
867 # - no more gmCLI
868 #
869 # Revision 1.4 2007/12/23 20:26:31 ncq
870 # - cleanup
871 #
872 # Revision 1.3 2007/12/23 12:07:40 ncq
873 # - cleanup
874 # - use gmCfg2
875 #
876 # Revision 1.2 2007/12/04 16:14:52 ncq
877 # - get_dbowner_connection()
878 #
879 # Revision 1.1 2007/12/04 16:03:43 ncq
880 # - merger of gmLogin and gmLoginDialog
881 #
882 #
883
884 #----------------------------------------------------------------
885 # old logs
886 #----------------------------------------------------------------
887 # Log: gmLogin.py,v
888 # Revision 1.37 2007/12/04 15:23:14 ncq
889 # - reorder connect_to_database()
890 # - check server settings sanity
891 #
892 # Revision 1.36 2007/11/09 14:40:33 ncq
893 # - gmPG2 dumps schema by itself now on hash mismatch
894 #
895 # Revision 1.35 2007/10/23 21:24:39 ncq
896 # - start backend listener on login
897 #
898 # Revision 1.34 2007/06/11 20:25:18 ncq
899 # - better logging
900 #
901 # Revision 1.33 2007/04/27 13:29:31 ncq
902 # - log schema dump on version conflict
903 #
904 # Revision 1.32 2007/03/18 14:10:07 ncq
905 # - do show schema mismatch warning even if --override-schema-check
906 #
907 # Revision 1.31 2007/03/08 11:41:55 ncq
908 # - set default client encoding from here
909 # - save state when --override-schema-check == True, too
910 #
911 # Revision 1.30 2006/12/15 15:27:01 ncq
912 # - move database schema version check here
913 #
914 # Revision 1.29 2006/10/25 07:46:44 ncq
915 # - Format() -> strftime() since datetime.datetime does not have .Format()
916 #
917 # Revision 1.28 2006/10/25 07:21:57 ncq
918 # - no more gmPG
919 #
920 # Revision 1.27 2006/10/24 13:25:19 ncq
921 # - Login() -> connect_to_database()
922 # - make gmPG2 main connection provider, piggyback gmPG onto it for now
923 #
924 # Revision 1.26 2006/10/08 11:04:45 ncq
925 # - simplify wx import
926 # - piggyback gmPG2 until gmPG is pruned
927 #
928 # Revision 1.25 2006/01/03 12:12:03 ncq
929 # - make epydoc happy re _()
930 #
931 # Revision 1.24 2005/09/27 20:44:59 ncq
932 # - wx.wx* -> wx.*
933 #
934 # Revision 1.23 2005/09/26 18:01:51 ncq
935 # - use proper way to import wx26 vs wx2.4
936 # - note: THIS WILL BREAK RUNNING THE CLIENT IN SOME PLACES
937 # - time for fixup
938 #
939 # Revision 1.22 2004/09/13 08:54:49 ncq
940 # - cleanup
941 # - use gmGuiHelpers
942 #
943 # Revision 1.21 2004/07/18 20:30:54 ncq
944 # - wxPython.true/false -> Python.True/False as Python tells us to do
945 #
946 # Revision 1.20 2004/06/20 16:01:05 ncq
947 # - please epydoc more carefully
948 #
949 # Revision 1.19 2004/06/20 06:49:21 ihaywood
950 # changes required due to Epydoc's OCD
951 #
952 # Revision 1.18 2004/03/04 19:47:06 ncq
953 # - switch to package based import: from Gnumed.foo import bar
954 #
955 # Revision 1.17 2003/11/17 10:56:38 sjtan
956 #
957 # synced and commiting.
958 #
959 # Revision 1.1 2003/10/23 06:02:39 sjtan
960 #
961 # manual edit areas modelled after r.terry's specs.
962 #
963 # Revision 1.16 2003/06/26 21:40:29 ncq
964 # - fatal->verbose
965 #
966 # Revision 1.15 2003/02/07 14:28:05 ncq
967 # - cleanup, cvs keywords
968 #
969 # @change log:
970 # 29.10.2001 hherb first draft, untested
971 #
972 #----------------------------------------------------------------
973 # Log: gmLoginDialog.py,v
974 # Revision 1.90 2007/10/22 12:38:32 ncq
975 # - default db change
976 #
977 # Revision 1.89 2007/10/07 12:32:41 ncq
978 # - workplace property now on gmSurgery.gmCurrentPractice() borg
979 #
980 # Revision 1.88 2007/09/20 19:07:38 ncq
981 # - port 5432 on salaam again
982 #
983 # Revision 1.87 2007/09/04 23:30:28 ncq
984 # - support --slave and slave mode checkbox
985 #
986 # Revision 1.86 2007/08/07 21:42:40 ncq
987 # - cPaths -> gmPaths
988 #
989 # Revision 1.85 2007/06/14 21:55:49 ncq
990 # - try to fix wx2.8 problem with size
991 #
992 # Revision 1.84 2007/06/11 20:25:55 ncq
993 # - bump database version
994 #
995 # Revision 1.83 2007/06/10 10:17:54 ncq
996 # - fix when no --debug
997 #
998 # Revision 1.82 2007/05/22 13:35:11 ncq
999 # - default port 5433 now on salaam
1000 #
1001 # Revision 1.81 2007/05/08 11:16:10 ncq
1002 # - set debugging flag based on user checkbox selection
1003 #
1004 # Revision 1.80 2007/05/07 12:33:31 ncq
1005 # - use gmTools.cPaths
1006 # - support debug mode checkbox
1007 #
1008 # Revision 1.79 2007/04/11 20:45:01 ncq
1009 # - no more 'resource dir'
1010 #
1011 # Revision 1.78 2007/04/02 15:15:19 ncq
1012 # - v5 -> v6
1013 #
1014 # Revision 1.77 2007/03/08 16:20:50 ncq
1015 # - need to reference proper cfg file
1016 #
1017 # Revision 1.76 2007/03/08 11:46:23 ncq
1018 # - restructured
1019 # - cleanup
1020 # - no more cLoginParamChoices
1021 # - no more loginparams keyword
1022 # - properly set user preferences file
1023 # - backend profile now can contain per-profile default encoding
1024 # - support system-wide profile pre-defs in /etc/gnumed/gnumed-client.conf
1025 #
1026 # Revision 1.75 2007/02/17 14:13:11 ncq
1027 # - gmPerson.gmCurrentProvider().workplace now property
1028 #
1029 # Revision 1.74 2007/01/30 17:40:22 ncq
1030 # - cleanup, get rid of wxMAC IFDEF
1031 # - use user preferences file for storing login preferences
1032 #
1033 # Revision 1.73 2006/12/21 16:54:32 ncq
1034 # - inage handlers already inited
1035 #
1036 # Revision 1.72 2006/12/15 15:27:28 ncq
1037 # - cleanup
1038 #
1039 # Revision 1.71 2006/10/25 07:21:57 ncq
1040 # - no more gmPG
1041 #
1042 # Revision 1.70 2006/09/01 14:45:03 ncq
1043 # - assume conf file is latin1 ... FIX later !
1044 #
1045 # Revision 1.69 2006/07/30 17:50:03 ncq
1046 # - properly load bitmaps
1047 #
1048 # Revision 1.68 2006/05/15 07:05:07 ncq
1049 # - must import gmPerson now
1050 #
1051 # Revision 1.67 2006/05/14 21:44:22 ncq
1052 # - add get_workplace() to gmPerson.gmCurrentProvider and make use thereof
1053 # - remove use of gmWhoAmI.py
1054 #
1055 # Revision 1.66 2006/05/12 12:18:11 ncq
1056 # - whoami -> whereami cleanup
1057 # - use gmCurrentProvider()
1058 #
1059 # Revision 1.65 2005/09/28 21:27:30 ncq
1060 # - a lot of wx2.6-ification
1061 #
1062 # Revision 1.64 2005/09/27 20:44:59 ncq
1063 # - wx.wx* -> wx.*
1064 #
1065 # Revision 1.63 2005/09/26 18:01:51 ncq
1066 # - use proper way to import wx26 vs wx2.4
1067 # - note: THIS WILL BREAK RUNNING THE CLIENT IN SOME PLACES
1068 # - time for fixup
1069 #
1070 # Revision 1.62 2005/09/24 09:17:29 ncq
1071 # - some wx2.6 compatibility fixes
1072 #
1073 # Revision 1.61 2005/08/15 15:15:25 ncq
1074 # - improved error message
1075 #
1076 # Revision 1.60 2005/08/14 15:22:04 ncq
1077 # - need to import gmNull
1078 #
1079 # Revision 1.59 2005/08/14 14:31:53 ncq
1080 # - better handling of missing/malformed config file
1081 #
1082 # Revision 1.58 2005/06/10 16:09:36 shilbert
1083 # foo.AddSizer()-> foo.Add() such that wx2.5 works
1084 #
1085 # Revision 1.57 2005/03/06 14:54:19 ncq
1086 # - szr.AddWindow() -> Add() such that wx2.5 works
1087 # - 'demographic record' -> get_identity()
1088 #
1089 # Revision 1.56 2005/01/22 22:26:06 ncq
1090 # - a bunch of cleanups
1091 # - i18n
1092 #
1093 # Revision 1.55 2005/01/20 21:37:40 hinnef
1094 # - added error dialog when no profiles specified
1095 #
1096 # Revision 1.54 2004/11/24 21:16:33 hinnef
1097 # - fixed issue with missing profiles when writing to empty gnumed.conf.
1098 # This lead to a crash when trying to load the invalid gnumed.conf.
1099 # Now we just ignore this and fall back to defaults.
1100 #
1101 # Revision 1.53 2004/11/22 19:32:36 hinnef
1102 # new login dialog with profiles
1103 #
1104 # Revision 1.52 2004/09/13 08:57:33 ncq
1105 # - losts of cleanup
1106 # - opt/tty not used in DSN anymore
1107 # - --slave -> gb['main.slave_mode']
1108 #
1109 # Revision 1.51 2004/07/18 20:30:54 ncq
1110 # - wxPython.true/false -> Python.True/False as Python tells us to do
1111 #
1112 # Revision 1.50 2004/07/18 18:44:27 ncq
1113 # - use Python True, not wxPython true
1114 #
1115 # Revision 1.49 2004/06/20 16:01:05 ncq
1116 # - please epydoc more carefully
1117 #
1118 # Revision 1.48 2004/06/20 06:49:21 ihaywood
1119 # changes required due to Epydoc's OCD
1120 #
1121 # Revision 1.47 2004/05/28 13:06:41 ncq
1122 # - improve faceName/Mac OSX fix
1123 #
1124 # Revision 1.46 2004/05/28 09:09:34 shilbert
1125 # - remove faceName option from wx.Font on wxMac or else no go
1126 #
1127 # Revision 1.45 2004/05/26 20:35:23 ncq
1128 # - don't inherit from LoginDialog in OptionWindow, it barks on MacOSX
1129 #
1130 # Revision 1.44 2004/04/24 12:46:35 ncq
1131 # - logininfo() needs host=
1132 #
1133 # Revision 1.43 2004/03/04 19:47:06 ncq
1134 # - switch to package based import: from Gnumed.foo import bar
1135 #
1136 # Revision 1.42 2003/12/29 16:58:52 uid66147
1137 # - use whoami
1138 #
1139 # Revision 1.41 2003/11/17 10:56:38 sjtan
1140 #
1141 # synced and commiting.
1142 #
1143 # Revision 1.1 2003/10/23 06:02:39 sjtan
1144 #
1145 # manual edit areas modelled after r.terry's specs.
1146 #
1147 # Revision 1.40 2003/06/17 19:27:44 ncq
1148 # - cleanup
1149 # - only use cfg file login params if not empty list
1150 #
1151 # Revision 1.39 2003/05/17 17:30:36 ncq
1152 # - just some cleanup
1153 #
1154 # Revision 1.38 2003/05/12 09:01:45 ncq
1155 # - 1) type(tmp) is types.ListType implies tmp != None
1156 # - 2) check for ListType, not StringType
1157 #
1158 # Revision 1.37 2003/05/10 18:48:09 hinnef
1159 # - added stricter type checks when reading from cfg-file
1160 #
1161 # Revision 1.36 2003/04/05 00:37:46 ncq
1162 # - renamed a few variables to reflect reality
1163 #
1164 # Revision 1.35 2003/03/31 00:18:34 ncq
1165 # - or so I thought
1166 #
1167 # Revision 1.34 2003/03/31 00:17:43 ncq
1168 # - started cleanup/clarification
1169 # - made saving of values work again
1170 #
1171 # Revision 1.33 2003/02/09 18:55:47 ncq
1172 # - make comment less angry
1173 #
1174 # Revision 1.32 2003/02/08 00:32:30 ncq
1175 # - fixed failure to detect config file
1176 #
1177 # Revision 1.31 2003/02/08 00:15:17 ncq
1178 # - cvs metadata keywords
1179 #
1180 # Revision 1.30 2003/02/07 21:06:02 sjtan
1181 #
1182 # refactored edit_area_gen_handler to handler_generator and handler_gen_editarea. New handler for gmSelectPerson
1183 #
1184 # Revision 1.29 2003/02/02 07:38:29 michaelb
1185 # set serpent as window icon - login dialog & option dialog
1186 #
1187 # Revision 1.28 2003/01/16 09:22:28 ncq
1188 # - changed default workplace name to "__default__" to play better with the database
1189 #
1190 # Revision 1.27 2003/01/07 10:22:52 ncq
1191 # - fixed font definition
1192 #
1193 # Revision 1.26 2002/09/21 14:49:22 ncq
1194 # - cleanup related to gmi18n
1195 #
1196 # Revision 1.25 2002/09/12 23:19:27 ncq
1197 # - cleanup in preparation of cleansing
1198 #
1199 # Revision 1.24 2002/09/10 08:54:35 ncq
1200 # - remember workplace name once loaded
1201 #
1202 # Revision 1.23 2002/09/09 01:05:16 ncq
1203 # - fixed i18n glitch
1204 # - added note that _("") is invalid !!
1205 #
1206 # @change log:
1207 # 10.10.2001 hherb initial implementation, untested
1208 # 24.10.2001 hherb comments added
1209 # 24.10.2001 hherb LoginDialog class added,
1210 # 24.10.2001 hherb persistent changes across multiple processes enabled
1211 # 25.10.2001 hherb more flexible configuration options, more commenting
1212 # 07.02.2002 hherb saved parameters now showing corectly in combo boxes
1213 # 05.09.2002 hberger moved options to own dialog
1214 # 06.09.2002 rterry simplified gui
1215 # -duplication and visual clutter removed
1216 # removed duplication of information in display
1217 # login gone from title bar , occurs once only now
1218 # visually highlighted in dark blue
1219 # login button title now 'ok' to conform to usual defaults of
1220 # ok, cancel in most operating systems
1221 # reference to help removed (have help button for that)
1222 # date removed - can't see use of this in login - clutters
1223 # 06.09.2002 hberger removed old code, fixed "login on close window" bug
1224 # 07.09.2002 rterry removed duplicated heading in advanced login options
1225
| Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Tue Feb 9 04:01:53 2010 | http://epydoc.sourceforge.net |