Manage custom login process
The password is removed from the login window. The login parameters are filled using asks pop-up until login success. The same login method is used to renew the session. issue5521 review23011002
This commit is contained in:
1 parent
5e7fc37b10
commit
2f065da300
6 files changed
+88
-92
No files matched your search
@@ -1,3 +1,4 @@
|
||||
* Manage custom login process
|
||||
* Add clear icon on Many2One
|
||||
* Re-position icons on Many2One widget
|
||||
|
||||
|
||||
+46
-22
@@ -1082,31 +1082,25 @@ def process_exception(exception, *args, **kwargs):
|
||||
elif exception.faultCode.startswith('403'):
|
||||
from tryton.gui.main import Main
|
||||
if not PLOCK.acquire(False):
|
||||
return False
|
||||
hostname = rpc._HOST
|
||||
port = rpc._PORT
|
||||
return
|
||||
language = CONFIG['client.lang']
|
||||
func = lambda parameters: rpc.login(
|
||||
rpc._HOST, rpc._PORT, rpc._DATABASE, rpc._USERNAME, parameters,
|
||||
language)
|
||||
try:
|
||||
while True:
|
||||
password = ask(_('Password:'), visibility=False)
|
||||
if password is None:
|
||||
Main.get_main().sig_quit()
|
||||
res = rpc.login(rpc._USERNAME, password, hostname, port,
|
||||
rpc._DATABASE)
|
||||
if res == -1:
|
||||
message(_('Connection error!\n'
|
||||
'Unable to connect to the server!'))
|
||||
return False
|
||||
if res < 0:
|
||||
continue
|
||||
if args:
|
||||
try:
|
||||
return rpc_execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
return process_exception(exception, *args,
|
||||
rpc_execute=rpc_execute)
|
||||
return True
|
||||
Login(func)
|
||||
except TrytonError, exception:
|
||||
if exception.faultCode == 'QueryCanceled':
|
||||
Main.get_main().sig_quit()
|
||||
raise
|
||||
finally:
|
||||
PLOCK.release()
|
||||
if args:
|
||||
try:
|
||||
return rpc_execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
return process_exception(exception, *args,
|
||||
rpc_execute=rpc_execute)
|
||||
elif isinstance(exception, (socket.error, TrytonServerUnavailable)):
|
||||
warning(str(exception), _('Network Error!'))
|
||||
return False
|
||||
@@ -1120,6 +1114,36 @@ def process_exception(exception, *args, **kwargs):
|
||||
return False
|
||||
|
||||
|
||||
class Login(object):
|
||||
def __init__(self, func):
|
||||
parameters = {}
|
||||
while True:
|
||||
try:
|
||||
func(parameters)
|
||||
except TrytonServerError, exception:
|
||||
if exception.faultCode.startswith('403'):
|
||||
parameters.clear()
|
||||
continue
|
||||
if exception.faultCode != 'LoginException':
|
||||
raise
|
||||
name, message, type = exception.args
|
||||
value = getattr(self, 'get_%s' % type)(message)
|
||||
if value is None:
|
||||
raise TrytonError('QueryCanceled')
|
||||
parameters[name] = value
|
||||
continue
|
||||
else:
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def get_char(self, message):
|
||||
return ask(message)
|
||||
|
||||
@classmethod
|
||||
def get_password(self, message):
|
||||
return ask(message, visibility=False)
|
||||
|
||||
|
||||
def node_attributes(node):
|
||||
result = {}
|
||||
attrs = node.attributes
|
||||
|
||||
+14
-21
@@ -874,32 +874,25 @@ class Main(object):
|
||||
self._sig_remove_book(widget,
|
||||
self.notebook.get_nth_page(self.notebook.get_current_page()))
|
||||
|
||||
def sig_login(self, widget=None, res=None):
|
||||
def sig_login(self, widget=None):
|
||||
if not self.sig_logout(widget, disconnect=False):
|
||||
return
|
||||
if not res:
|
||||
try:
|
||||
res = DBLogin().run()
|
||||
except TrytonError, exception:
|
||||
if exception.faultCode == 'QueryCanceled':
|
||||
return False
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception)
|
||||
return
|
||||
language = CONFIG['client.lang']
|
||||
host, port, database, username = DBLogin().run()
|
||||
func = lambda parameters: rpc.login(
|
||||
host, port, database, username, parameters, language)
|
||||
try:
|
||||
log_response = rpc.login(*res)
|
||||
except TrytonServerError, exception:
|
||||
common.Login(func)
|
||||
except Exception, exception:
|
||||
if (isinstance(exception, TrytonError)
|
||||
and exception.faultCode == 'QueryCanceled'):
|
||||
return
|
||||
if (isinstance(exception, TrytonServerError)
|
||||
and exception.faultCode.startswith('403')):
|
||||
return self.sig_login()
|
||||
common.process_exception(exception)
|
||||
return
|
||||
if log_response > 0:
|
||||
self.get_preferences()
|
||||
elif log_response == -1:
|
||||
common.message(_('Connection error!\n'
|
||||
'Unable to connect to the server!'))
|
||||
elif log_response == -2:
|
||||
common.message(_('Connection error!\n'
|
||||
'Bad username or password!'))
|
||||
return self.sig_login()
|
||||
self.get_preferences()
|
||||
self.favorite_unset()
|
||||
self.menuitem_favorite.set_sensitive(True)
|
||||
self.menuitem_user.set_sensitive(True)
|
||||
|
||||
@@ -443,19 +443,9 @@ class DBLogin(object):
|
||||
self.table_main.attach(self.label_database, 0, 1, 5, 6,
|
||||
xoptions=gtk.FILL)
|
||||
self.table_main.attach(self.entry_database, 1, 3, 5, 6)
|
||||
self.entry_password = gtk.Entry()
|
||||
self.entry_password.set_visibility(False)
|
||||
self.entry_password.set_activates_default(True)
|
||||
self.table_main.attach(self.entry_password, 1, 3, 7, 8)
|
||||
self.entry_login = gtk.Entry()
|
||||
self.entry_login.set_activates_default(True)
|
||||
self.table_main.attach(self.entry_login, 1, 3, 6, 7)
|
||||
label_password = gtk.Label(str=_("Password:"))
|
||||
label_password.set_justify(gtk.JUSTIFY_RIGHT)
|
||||
label_password.set_alignment(1, 0.5)
|
||||
label_password.set_padding(3, 3)
|
||||
label_password.set_mnemonic_widget(self.entry_password)
|
||||
self.table_main.attach(label_password, 0, 1, 7, 8, xoptions=gtk.FILL)
|
||||
label_username = gtk.Label(str=_("User name:"))
|
||||
label_username.set_alignment(1, 0.5)
|
||||
label_username.set_padding(3, 3)
|
||||
@@ -572,10 +562,7 @@ class DBLogin(object):
|
||||
self.entry_login.set_text(CONFIG['login.login'])
|
||||
self.dialog.show_all()
|
||||
|
||||
if not self.entry_login.get_text():
|
||||
self.entry_login.grab_focus()
|
||||
else:
|
||||
self.entry_password.grab_focus()
|
||||
self.entry_login.grab_focus()
|
||||
|
||||
# Reshow dialog for gtk-quarks
|
||||
self.dialog.reshow_with_initial_size()
|
||||
@@ -583,10 +570,10 @@ class DBLogin(object):
|
||||
# The previous action did not called expand_hostspec
|
||||
self.expand_hostspec(self.expander)
|
||||
|
||||
res, result = None, ('', '', '', '', '')
|
||||
response, result = None, ('', '', '', '')
|
||||
while not all(result):
|
||||
res = self.dialog.run()
|
||||
if res != gtk.RESPONSE_OK:
|
||||
response = self.dialog.run()
|
||||
if response != gtk.RESPONSE_OK:
|
||||
break
|
||||
active_profile = self.combo_profile.get_active()
|
||||
if active_profile != -1:
|
||||
@@ -610,12 +597,12 @@ class DBLogin(object):
|
||||
CONFIG['login.db'] = database
|
||||
CONFIG['login.expanded'] = self.expander.props.expanded
|
||||
CONFIG['login.login'] = login
|
||||
result = (self.entry_login.get_text(),
|
||||
self.entry_password.get_text(), host, port, database)
|
||||
result = (
|
||||
host, port, database, self.entry_login.get_text())
|
||||
|
||||
self.parent.present()
|
||||
self.dialog.destroy()
|
||||
if res != gtk.RESPONSE_OK:
|
||||
if response != gtk.RESPONSE_OK:
|
||||
rpc.logout()
|
||||
raise TrytonError('QueryCanceled')
|
||||
return result
|
||||
@@ -6,9 +6,9 @@ import gtk
|
||||
import copy
|
||||
from tryton.gui.window.view_form.screen import Screen
|
||||
from tryton.config import TRYTON_ICON
|
||||
import tryton.common as common
|
||||
from tryton.common import RPCExecute, RPCException
|
||||
from tryton.common import RPCExecute, RPCException, process_exception, Login
|
||||
from tryton.gui.window.nomodal import NoModal
|
||||
from tryton.exceptions import TrytonError
|
||||
import tryton.rpc as rpc
|
||||
|
||||
_ = gettext.gettext
|
||||
@@ -84,17 +84,16 @@ class Preference(NoModal):
|
||||
if response_id == gtk.RESPONSE_OK:
|
||||
if self.screen.current_record.validate():
|
||||
vals = copy.copy(self.screen.get())
|
||||
if 'password' in vals:
|
||||
password = common.ask(_('Current Password:'),
|
||||
visibility=False)
|
||||
if not password:
|
||||
return
|
||||
else:
|
||||
password = False
|
||||
context = rpc.CONTEXT.copy()
|
||||
func = lambda parameters: rpc.execute(
|
||||
'model', 'res.user', 'set_preferences', vals, parameters,
|
||||
context)
|
||||
try:
|
||||
RPCExecute('model', 'res.user', 'set_preferences',
|
||||
vals, password)
|
||||
except RPCException:
|
||||
Login(func)
|
||||
except TrytonError, exception:
|
||||
if exception.faultCode == 'QueryCanceled':
|
||||
return
|
||||
process_exception(exception)
|
||||
return
|
||||
self.parent.present()
|
||||
self.destroy()
|
||||
|
||||
+9
-17
@@ -69,27 +69,20 @@ def server_version(host, port):
|
||||
raise
|
||||
|
||||
|
||||
def login(username, password, host, port, database):
|
||||
def login(host, port, database, username, parameters, language=None):
|
||||
global CONNECTION, _USER, _USERNAME, _HOST, _PORT, _DATABASE
|
||||
global _VIEW_CACHE, _TOOLBAR_CACHE, _KEYWORD_CACHE
|
||||
_VIEW_CACHE = {}
|
||||
_TOOLBAR_CACHE = {}
|
||||
_KEYWORD_CACHE = {}
|
||||
try:
|
||||
if CONNECTION is not None:
|
||||
CONNECTION.close()
|
||||
CONNECTION = ServerPool(host, port, database)
|
||||
logging.getLogger(__name__).info('common.db.login(%s, %s)' %
|
||||
(username, 'x' * 10))
|
||||
with CONNECTION() as conn:
|
||||
result = conn.common.db.login(username, password)
|
||||
logging.getLogger(__name__).debug(repr(result))
|
||||
except socket.error:
|
||||
_USER = None
|
||||
return -1
|
||||
if not result:
|
||||
_USER = None
|
||||
return -2
|
||||
if CONNECTION is not None:
|
||||
CONNECTION.close()
|
||||
CONNECTION = ServerPool(host, port, database)
|
||||
logging.getLogger(__name__).info('common.db.login(%s, %s, %s)'
|
||||
% (username, 'x' * 10, language))
|
||||
with CONNECTION() as conn:
|
||||
result = conn.common.db.login(username, parameters, language)
|
||||
logging.getLogger(__name__).debug(repr(result))
|
||||
_USER = result[0]
|
||||
_USERNAME = username
|
||||
session = ':'.join(map(str, [username] + result))
|
||||
@@ -98,7 +91,6 @@ def login(username, password, host, port, database):
|
||||
_PORT = port
|
||||
_DATABASE = database
|
||||
IPCServer(host, port, database).run()
|
||||
return 1
|
||||
|
||||
|
||||
def logout():
|
||||
|
||||
Reference in new issue
Block a user