1
2 """GNUmed authentication widgets.
3
4 This module contains widgets and GUI
5 functions for authenticating users.
6 """
7
8 __author__ = "karsten.hilbert@gmx.net, H.Herb, H.Berger, R.Terry"
9 __license__ = "GPL v2 or later (details at http://www.gnu.org)"
10
11
12
13 import sys
14 import os.path
15 import logging
16 import re as regex
17
18
19
20 import wx
21
22
23
24 if __name__ == '__main__':
25 sys.path.insert(0, '../../')
26 from Gnumed.pycommon import gmLoginInfo
27 from Gnumed.pycommon import gmPG2
28 from Gnumed.pycommon import gmBackendListener
29 from Gnumed.pycommon import gmTools
30 from Gnumed.pycommon import gmCfg2
31 from Gnumed.pycommon import gmI18N
32
33 from Gnumed.business import gmPraxis
34
35 from Gnumed.wxpython import gmGuiHelpers
36 from Gnumed.wxpython import gmExceptionHandlingWidgets
37
38
39 _log = logging.getLogger('gm.ui')
40 _cfg = gmCfg2.gmCfgData()
41
42 try:
43 _('dummy-no-need-to-translate-but-make-epydoc-happy')
44 except NameError:
45 _ = lambda x:x
46
47
48 msg_generic = _("""
49 GNUmed database version mismatch.
50
51 This database version cannot be used with this client:
52
53 client version: %s
54 database version detected: %s
55 database version needed: %s
56
57 Currently connected to database:
58
59 host: %s
60 database: %s
61 user: %s
62 """)
63
64 msg_time_skew_fail = _("""\
65 The server and client clocks are off
66 by more than %s minutes !
67
68 You must fix the time settings before
69 you can use this database with this
70 client.
71
72 You may have to contact your
73 administrator for help.""")
74
75 msg_time_skew_warn = _("""\
76 The server and client clocks are off
77 by more than %s minutes !
78
79 You should fix the time settings.
80 Otherwise clinical data may appear to
81 have been entered at the wrong time.
82
83 You may have to contact your
84 administrator for help.""")
85
86 msg_insanity = _("""
87 There is a serious problem with the database settings:
88
89 %s
90
91 You may have to contact your administrator for help.""")
92
93 msg_fail = _("""
94 You must connect to a different database in order
95 to use the GNUmed client. You may have to contact
96 your administrator for help.""")
97
98 msg_override = _("""
99 The client will, however, continue to start up because
100 you are running a development/test version of GNUmed.
101
102 There may be schema related errors. Please report and/or
103 fix them. Do not rely on this database to work properly
104 in all cases !""")
105
106
107
108
110 """Display the login dialog and try to log into the backend.
111
112 - up to max_attempts times
113 - returns True/False
114 """
115
116 expected_hash = gmPG2.known_schema_hashes[expected_version]
117 client_version = _cfg.get(option = u'client_version')
118 global current_db_name
119 current_db_name = u'gnumed_v%s' % expected_version
120
121 attempt = 0
122
123 dlg = cLoginDialog(None, -1, client_version = client_version)
124 dlg.Centre(wx.BOTH)
125
126 while attempt < max_attempts:
127
128 _log.debug('login attempt %s of %s', (attempt+1), max_attempts)
129
130 connected = False
131
132 dlg.ShowModal()
133 login = dlg.panel.GetLoginInfo()
134 if login is None:
135 _log.info("user cancelled login dialog")
136 break
137
138
139 dsn = gmPG2.make_psycopg2_dsn (
140 database = login.database,
141 host = login.host,
142 port = login.port,
143 user = login.user,
144 password = login.password
145 )
146 try:
147 conn = gmPG2.get_raw_connection(dsn = dsn, verbose = True, readonly = True)
148 connected = True
149
150 except gmPG2.cAuthenticationError, e:
151 attempt += 1
152 _log.error(u"login attempt failed: %s", e)
153 if attempt < max_attempts:
154 if (u'host=127.0.0.1' in (u'%s' % e)) or (u'host=' not in (u'%s' % e)):
155 msg = _(
156 'Unable to connect to database:\n\n'
157 '%s\n\n'
158 "Are you sure you have got a local database installed ?\n"
159 '\n'
160 "Please retry with proper credentials or cancel.\n"
161 '\n'
162 ' (for the public and any new GNUmed data-\n'
163 ' bases the default user name and password\n'
164 ' are {any-doc, any-doc})\n'
165 '\n'
166 'You may also need to check the PostgreSQL client\n'
167 'authentication configuration in pg_hba.conf. For\n'
168 'details see:\n'
169 '\n'
170 'wiki.gnumed.de/bin/view/Gnumed/ConfigurePostgreSQL'
171 )
172 else:
173 msg = _(
174 "Unable to connect to database:\n\n"
175 "%s\n\n"
176 "Please retry with proper credentials or cancel.\n"
177 "\n"
178 "For the public and any new GNUmed databases the\n"
179 "default user name and password are {any-doc, any-doc}.\n"
180 "\n"
181 'You may also need to check the PostgreSQL client\n'
182 'authentication configuration in pg_hba.conf. For\n'
183 'details see:\n'
184 '\n'
185 'wiki.gnumed.de/bin/view/Gnumed/ConfigurePostgreSQL'
186 )
187 msg = msg % e
188 msg = regex.sub(r'password=[^\s]+', u'password=%s' % gmTools.u_replacement_character, msg)
189 gmGuiHelpers.gm_show_error (
190 msg,
191 _('Connecting to backend')
192 )
193 del e
194 continue
195
196 except gmPG2.dbapi.OperationalError, e:
197 _log.error(u"login attempt failed: %s", e)
198 msg = _(
199 "Unable to connect to database:\n\n"
200 "%s\n\n"
201 "Please retry another backend / user / password combination !\n"
202 "\n"
203 " (for the public and any new GNUmed databases\n"
204 " the default user name and password are\n"
205 " {any-doc, any-doc})\n"
206 "\n"
207 ) % gmPG2.extract_msg_from_pg_exception(e)
208 msg = regex.sub(r'password=[^\s]+', u'password=%s' % gmTools.u_replacement_character, msg)
209 gmGuiHelpers.gm_show_error (
210 msg,
211 _('Connecting to backend')
212 )
213 del e
214 continue
215
216
217 gmPG2.set_default_login(login = login)
218 gmPG2.set_default_client_encoding(encoding = dlg.panel.backend_profile.encoding)
219
220 seems_bootstrapped = gmPG2.schema_exists(schema = 'gm')
221 if not seems_bootstrapped:
222 _log.error('schema [gm] does not exist - database not bootstrapped ?')
223 msg = _(
224 'The database you connected to does not seem\n'
225 'to have been boostrapped properly.\n'
226 '\n'
227 'Make sure you have run the GNUmed database\n'
228 'bootstrapper tool to create a new database.\n'
229 '\n'
230 'Further help can be found on the website at\n'
231 '\n'
232 ' http://wiki.gnumed.de\n'
233 '\n'
234 'or on the GNUmed mailing list.'
235 )
236 gmGuiHelpers.gm_show_error(msg, _('Verifying database'))
237 connected = False
238 break
239
240 compatible = gmPG2.database_schema_compatible(version = expected_version)
241 if compatible or not require_version:
242 dlg.panel.save_state()
243
244 if not compatible:
245 connected_db_version = gmPG2.get_schema_version()
246 msg = msg_generic % (
247 client_version,
248 connected_db_version,
249 expected_version,
250 gmTools.coalesce(login.host, '<localhost>'),
251 login.database,
252 login.user
253 )
254 if require_version:
255 gmGuiHelpers.gm_show_error(msg + msg_fail, _('Verifying database version'))
256 connected = False
257 continue
258 gmGuiHelpers.gm_show_info(msg + msg_override, _('Verifying database version'))
259
260
261 max_skew = 1
262 if _cfg.get(option = 'debug'):
263 max_skew = 10
264 if not gmPG2.sanity_check_time_skew(tolerance = (max_skew * 60)):
265 if _cfg.get(option = 'debug'):
266 gmGuiHelpers.gm_show_warning(msg_time_skew_warn % max_skew, _('Verifying database settings'))
267 else:
268 gmGuiHelpers.gm_show_error(msg_time_skew_fail % max_skew, _('Verifying database settings'))
269 connected = False
270 continue
271
272 sanity_level, message = gmPG2.sanity_check_database_settings()
273 if sanity_level != 0:
274 gmGuiHelpers.gm_show_error((msg_insanity % message), _('Verifying database settings'))
275 if sanity_level == 2:
276 connected = False
277 continue
278
279 gmExceptionHandlingWidgets.set_is_public_database(login.public_db)
280 gmExceptionHandlingWidgets.set_helpdesk(login.helpdesk)
281
282 listener = gmBackendListener.gmBackendListener(conn = conn)
283 break
284
285 dlg.Destroy()
286
287 return connected
288
290 if procedure is None:
291 procedure = _('<restricted procedure>')
292
293
294 if dbo_password is None:
295 dbo_password = wx.GetPasswordFromUser (
296 message = _("""
297 [%s]
298
299 This is a restricted procedure. We need the
300 current password for the GNUmed database owner.
301
302 Please enter the current password for <%s>:""") % (
303 procedure,
304 dbo_account
305 ),
306 caption = procedure
307 )
308 if dbo_password == '':
309 return None
310
311
312 login = gmPG2.get_default_login()
313 dsn = gmPG2.make_psycopg2_dsn (
314 database = login.database,
315 host = login.host,
316 port = login.port,
317 user = dbo_account,
318 password = dbo_password
319 )
320 try:
321 conn = gmPG2.get_connection (
322 dsn = dsn,
323 readonly = False,
324 verbose = True,
325 pooled = False
326 )
327 except:
328 _log.exception('cannot connect')
329 gmGuiHelpers.gm_show_error (
330 aMessage = _('Cannot connect as the GNUmed database owner <%s>.') % dbo_account,
331 aTitle = procedure
332 )
333 gmPG2.log_database_access(action = u'failed to connect as database owner for [%s]' % procedure)
334 return None
335
336 return conn
337
339
340 title = _(u'Changing GNUmed database owner password')
341
342 dbo_account = wx.GetTextFromUser (
343 message = _(u"Enter the account name of the GNUmed database owner:"),
344 caption = title,
345 default_value = u''
346 )
347
348 if dbo_account.strip() == u'':
349 return False
350
351 dbo_conn = get_dbowner_connection (
352 procedure = title,
353 dbo_account = dbo_account
354 )
355 if dbo_conn is None:
356 return False
357
358 dbo_pwd_new_1 = wx.GetPasswordFromUser (
359 message = _(u"Enter the NEW password for the GNUmed database owner:"),
360 caption = title
361 )
362 if dbo_pwd_new_1.strip() == u'':
363 return False
364
365 dbo_pwd_new_2 = wx.GetPasswordFromUser (
366 message = _(u"""Enter the NEW password for the GNUmed database owner, again.
367
368 (This will protect you from typos.)
369 """),
370 caption = title
371 )
372 if dbo_pwd_new_2.strip() == u'':
373 return False
374
375 if dbo_pwd_new_1 != dbo_pwd_new_2:
376 return False
377
378 cmd = u"""ALTER ROLE "%s" ENCRYPTED PASSWORD '%s';""" % (
379 dbo_account,
380 dbo_pwd_new_2
381 )
382 gmPG2.run_rw_queries(link_obj = dbo_conn, queries = [{'cmd': cmd}], end_tx = True)
383
384 return True
385
388
390 """cLoginDialog - window holding cLoginPanel"""
391
392 - def __init__(self, parent, id, title = _("Welcome to"), client_version = u'*** unknown ***'):
393 wx.Dialog.__init__(self, parent, id, title)
394 self.panel = cLoginPanel(self, -1, isDialog=1, client_version = client_version)
395 self.Fit()
396 self.Centre()
397
398 self.SetIcon(gmTools.get_icon(wx = wx))
399
401 """GUI panel class that interactively gets Postgres login parameters.
402
403 It features combo boxes which "remember" any number of
404 previously entered settings.
405 """
406 - def __init__(self, parent, id,
407 pos = wx.DefaultPosition, size = wx.DefaultSize, style = wx.TAB_TRAVERSAL,
408 isDialog = 0, client_version = u'*** unknown ***'):
409 """Create login panel.
410
411 isDialog: if this panel is the main panel of a dialog, the panel will
412 resize the dialog automatically to display everything neatly
413 if isDialog is set to True
414 """
415 wx.Panel.__init__(self, parent, id, pos, size, style)
416 self.parent = parent
417
418
419
420 self.cancelled = True
421
422
423 self.isDialog = isDialog
424
425 self.topsizer = wx.BoxSizer(wx.VERTICAL)
426
427
428 paths = gmTools.gmPaths(app_name = u'gnumed', wx = wx)
429 bitmap = os.path.join(paths.system_app_data_dir, 'bitmaps', 'gnumedlogo.png')
430 try:
431 png = wx.Image(bitmap, wx.BITMAP_TYPE_PNG).ConvertToBitmap()
432 bmp = wx.StaticBitmap(self, -1, png, wx.Point(10, 10), wx.Size(png.GetWidth(), png.GetHeight()))
433 self.topsizer.Add (
434 bmp,
435 proportion = 0,
436 flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_CENTER_HORIZONTAL|wx.ALL,
437 border = 10
438 )
439 except:
440 self.topsizer.Add (
441 wx.StaticText (
442 self,
443 -1,
444 label = _("Cannot find image") + bitmap,
445 style = wx.ALIGN_CENTRE
446 ),
447 proportion = 0,
448 flag = wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL,
449 border = 10
450 )
451
452 paramsbox_caption = _('Workplace "%s" (version %s)') % (gmPraxis.gmCurrentPraxisBranch().active_workplace, client_version)
453
454
455 self.paramsbox = wx.StaticBox( self, -1, paramsbox_caption, style = wx.ALIGN_CENTRE_HORIZONTAL)
456 self.paramsboxsizer = wx.StaticBoxSizer( self.paramsbox, wx.VERTICAL )
457 self.paramsbox.SetForegroundColour(wx.Colour(35, 35, 142))
458 self.paramsbox.SetFont(wx.Font(
459 pointSize = 12,
460 family = wx.SWISS,
461 style = wx.NORMAL,
462 weight = wx.BOLD,
463 underline = False
464 ))
465 self.pboxgrid = wx.FlexGridSizer(5, 2, 5, 5)
466 self.pboxgrid.AddGrowableCol(1)
467
468
469 label = wx.StaticText( self, -1, _('Log into'), wx.DefaultPosition, wx.DefaultSize, 0)
470 label.SetForegroundColour(wx.Colour(35, 35, 142))
471 self.pboxgrid.Add(label, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)
472 self.__backend_profiles = self.__get_backend_profiles()
473 self._CBOX_profile = wx.ComboBox (
474 self,
475 -1,
476 self.__backend_profiles.keys()[0],
477 wx.DefaultPosition,
478 size = wx.Size(550,-1),
479 choices = self.__backend_profiles.keys(),
480 style = wx.CB_READONLY
481 )
482 self.pboxgrid.Add (self._CBOX_profile, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
483
484
485 label = wx.StaticText( self, -1, _("Username"), wx.DefaultPosition, wx.DefaultSize, 0 )
486 label.SetForegroundColour(wx.Colour(35, 35, 142))
487 self.pboxgrid.Add(label, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
488 self.__previously_used_accounts = self.__get_previously_used_accounts()
489 self._CBOX_user = wx.ComboBox (
490 self,
491 -1,
492 self.__previously_used_accounts[0],
493 wx.DefaultPosition,
494 wx.Size(150,-1),
495 self.__previously_used_accounts,
496 wx.CB_DROPDOWN
497 )
498 self.pboxgrid.Add( self._CBOX_user, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
499
500
501 label = wx.StaticText( self, -1, _("Password"), wx.DefaultPosition, wx.DefaultSize, 0 )
502 label.SetForegroundColour(wx.Colour(35, 35, 142))
503 self.pboxgrid.Add( label, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
504 self.pwdentry = wx.TextCtrl( self, 1, '', wx.DefaultPosition, wx.Size(80,-1), wx.TE_PASSWORD )
505
506 self.pwdentry.SetFocus()
507 self.pboxgrid.Add( self.pwdentry, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
508
509
510 label = wx.StaticText(self, -1, _('Options'), wx.DefaultPosition, wx.DefaultSize, 0)
511 label.SetForegroundColour(wx.Colour(35, 35, 142))
512 self.pboxgrid.Add(label, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
513 self._CHBOX_debug = wx.CheckBox(self, -1, _('&Debug mode'))
514 self._CHBOX_debug.SetToolTipString(_('Check this to run GNUmed client in debugging mode.'))
515 self.pboxgrid.Add(self._CHBOX_debug, 0, wx.GROW | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)
516
517
518 label = wx.StaticText(self, -1, '', wx.DefaultPosition, wx.DefaultSize, 0)
519 label.SetForegroundColour(wx.Colour(35, 35, 142))
520 self.pboxgrid.Add(label, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
521 self._CHBOX_slave = wx.CheckBox(self, -1, _('Enable &remote control'))
522 self._CHBOX_slave.SetToolTipString(_('Check this to run GNUmed client in slave mode for remote control.'))
523 self.pboxgrid.Add(self._CHBOX_slave, 0, wx.GROW | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)
524
525
526
527
528
529
530
531
532
533
534
535
536
537 self.button_gridsizer = wx.GridSizer(1,3,0,0)
538
539
540
541 ID_BUTTON_LOGIN = wx.NewId()
542 button_login_ok = wx.Button(self, ID_BUTTON_LOGIN, _("&Ok"), wx.DefaultPosition, wx.DefaultSize, 0 )
543 button_login_ok.SetToolTip(wx.ToolTip(_("Proceed with login.")) )
544 button_login_ok.SetDefault()
545
546
547
548
549 ID_BUTTON_CANCEL = wx.NewId()
550 button_cancel = wx.Button(self, ID_BUTTON_CANCEL, _("&Cancel"), wx.DefaultPosition, wx.DefaultSize, 0 )
551 button_cancel.SetToolTip(wx.ToolTip(_("Cancel Login.")) )
552
553
554
555 ID_BUTTON_HELP = wx.NewId()
556 button_help = wx.Button(self, ID_BUTTON_HELP, _("&Help"), wx.DefaultPosition, wx.DefaultSize, 0 )
557 button_help.SetToolTip(wx.ToolTip(_("Help for login screen")))
558
559
560
561 self.button_gridsizer.Add (button_help,0,wx.EXPAND|wx.ALL,5)
562 self.button_gridsizer.Add (button_login_ok,0,wx.EXPAND|wx.ALL,5)
563 self.button_gridsizer.Add (button_cancel,0,wx.EXPAND|wx.ALL,5)
564
565 self.paramsboxsizer.Add(self.pboxgrid, 1, wx.GROW|wx.ALL, 10)
566 self.topsizer.Add(self.paramsboxsizer, 1, wx.GROW|wx.ALL, 10)
567 self.topsizer.Add( self.button_gridsizer, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
568
569 self.__load_state()
570
571 self.SetAutoLayout(True)
572 self.SetSizer( self.topsizer)
573 self.topsizer.Fit( self )
574 if self.isDialog:
575 self.topsizer.SetSizeHints(parent)
576
577 wx.EVT_BUTTON(self, ID_BUTTON_HELP, self.OnHelp)
578 wx.EVT_BUTTON(self, ID_BUTTON_LOGIN, self.__on_login_button_pressed)
579 wx.EVT_BUTTON(self, ID_BUTTON_CANCEL, self.OnCancel)
580
581
582
583
585
586 accounts = gmTools.coalesce (
587 _cfg.get (
588 group = u'backend',
589 option = u'logins',
590 source_order = [
591 (u'explicit', u'extend'),
592 (u'user', u'extend'),
593 (u'workbase', u'extend')
594 ]
595 ),
596 ['any-doc']
597 )
598
599
600 return accounts
601
603 """Get server profiles from the configuration files.
604
605 1) from system-wide file
606 2) from user file
607
608 Profiles in the user file which have the same name
609 as a profile in the system file will override the
610 system file.
611 """
612
613 src_order = [
614 (u'explicit', u'extend'),
615 (u'system', u'extend'),
616 (u'user', u'extend'),
617 (u'workbase', u'extend')
618 ]
619
620 profile_names = gmTools.coalesce (
621 _cfg.get(group = u'backend', option = u'profiles', source_order = src_order),
622 []
623 )
624
625
626 src_order = [
627 (u'explicit', u'return'),
628 (u'workbase', u'return'),
629 (u'user', u'return'),
630 (u'system', u'return')
631 ]
632
633 profiles = {}
634
635 for profile_name in profile_names:
636
637
638 profile = cBackendProfile()
639 profile_section = 'profile %s' % profile_name
640
641 profile.name = profile_name
642 profile.host = gmTools.coalesce(_cfg.get(profile_section, u'host', src_order), u'').strip()
643 port = gmTools.coalesce(_cfg.get(profile_section, u'port', src_order), 5432)
644 try:
645 profile.port = int(port)
646 if profile.port < 1024:
647 raise ValueError('refusing to use priviledged port (< 1024)')
648 except ValueError:
649 _log.warning('invalid port definition: [%s], skipping profile [%s]', port, profile_name)
650 continue
651 profile.database = gmTools.coalesce(_cfg.get(profile_section, u'database', src_order), u'').strip()
652 if profile.database == u'':
653 _log.warning('database name not specified, skipping profile [%s]', profile_name)
654 continue
655 profile.encoding = gmTools.coalesce(_cfg.get(profile_section, u'encoding', src_order), u'UTF8')
656 profile.public_db = bool(_cfg.get(profile_section, u'public/open access', src_order))
657 profile.helpdesk = _cfg.get(profile_section, u'help desk', src_order)
658
659 label = u'%s (%s@%s)' % (profile_name, profile.database, profile.host)
660 profiles[label] = profile
661
662
663
664 if not (_cfg.get(option = 'debug') or current_db_name.endswith('_devel')):
665 profiles2remove = []
666 for label in profiles:
667 if profiles[label].database != current_db_name:
668 profiles2remove.append(label)
669 for label in profiles2remove:
670 del profiles[label]
671
672 if len(profiles) == 0:
673 host = u'publicdb.gnumed.de'
674 label = u'public GNUmed database (%s@%s)' % (current_db_name, host)
675 profiles[label] = cBackendProfile()
676 profiles[label].name = label
677 profiles[label].host = host
678 profiles[label].port = 5432
679 profiles[label].database = current_db_name
680 profiles[label].encoding = u'UTF8'
681 profiles[label].public_db = True
682 profiles[label].helpdesk = u'http://wiki.gnumed.de'
683
684 return profiles
685
687
688 src_order = [
689 (u'explicit', u'return'),
690 (u'user', u'return'),
691 ]
692
693 self._CBOX_user.SetValue (
694 gmTools.coalesce (
695 _cfg.get(u'preferences', u'login', src_order),
696 self.__previously_used_accounts[0]
697 )
698 )
699
700 last_used_profile_label = _cfg.get(u'preferences', u'profile', src_order)
701 if last_used_profile_label in self.__backend_profiles.keys():
702 self._CBOX_profile.SetValue(last_used_profile_label)
703 else:
704 self._CBOX_profile.SetValue(self.__backend_profiles.keys()[0])
705
706 self._CHBOX_debug.SetValue(_cfg.get(option = 'debug'))
707 self._CHBOX_slave.SetValue(_cfg.get(option = 'slave'))
708
727
728
729
731 """convenience function for compatibility with gmLoginInfo.LoginInfo"""
732 if self.cancelled:
733 return None
734
735
736
737 profile = self.__backend_profiles[self._CBOX_profile.GetValue().encode('utf8').strip()]
738 _log.info(u'backend profile "%s" selected', profile.name)
739 _log.info(u' details: <%s> on %s@%s:%s (%s, %s)',
740 self._CBOX_user.GetValue(),
741 profile.database,
742 profile.host,
743 profile.port,
744 profile.encoding,
745 gmTools.bool2subst(profile.public_db, u'public', u'private')
746 )
747 _log.info(u' helpdesk: "%s"', profile.helpdesk)
748 login = gmLoginInfo.LoginInfo (
749 user = self._CBOX_user.GetValue(),
750 password = self.pwdentry.GetValue(),
751 host = profile.host,
752 database = profile.database,
753 port = profile.port
754 )
755 login.public_db = profile.public_db
756 login.helpdesk = profile.helpdesk
757 login.backend_profile = profile.name
758 return login
759
760
761
763 praxis = gmPraxis.gmCurrentPraxisBranch()
764 wx.MessageBox(_(
765 u"""Unable to connect to the database ?
766
767 "PostgreSQL: FATAL: password authentication failed ..."
768
769 The default user name and password are {any-doc, any-doc}
770 for the public and any new GNUmed databases.
771
772 "... could not connect to server ..."
773
774 Mostly this is a case of new users who did not yet install
775 or configure a PostgreSQL server and/or a GNUmed database
776 of their own, which you must do before you can connect to
777 anything other than the public demonstration database, see
778
779 http://wiki.gnumed.de/bin/view/Gnumed/GmManualServerInstall
780
781 For assistance on using GNUmed please consult the wiki:
782
783 http://wiki.gnumed.de/bin/view/Gnumed/GnumedManual
784
785 For more help than the above, please contact:
786
787 GNUmed Development List <gnumed-bugs@gnu.org>
788
789 For local assistance please contact:
790
791 %s""") % praxis.helpdesk,
792 caption = _('HELP for GNUmed main login screen'))
793
794
822
824 self.cancelled = True
825 self.parent.Close()
826
827
828
829
830 if __name__ == "__main__":
831
832 if len(sys.argv) < 2:
833 sys.exit()
834
835 if sys.argv[1] != 'test':
836 sys.exit()
837
838
839 sys.exit()
840
841 from Gnumed.pycommon import gmI18N
842
843 logging.basicConfig(level = logging.DEBUG)
844
845 gmI18N.activate_locale()
846 gmI18N.install_domain(domain='gnumed')
847
848
850 app = wx.PyWidgetTester(size = (300,400))
851
852
853
854 dlg = cLoginDialog(None, -1)
855 dlg.ShowModal()
856
857 lp = dlg.panel.GetLoginInfo()
858 if lp is None:
859 wx.MessageBox(_("Dialog was cancelled by user"))
860 else:
861 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()))
862 dlg.Destroy()
863
864
865
866