comparison sat/memory/params.py @ 3028:ab2696e34d29

Python 3 port: /!\ this is a huge commit /!\ starting from this commit, SàT is needs Python 3.6+ /!\ SàT maybe be instable or some feature may not work anymore, this will improve with time This patch port backend, bridge and frontends to Python 3. Roughly this has been done this way: - 2to3 tools has been applied (with python 3.7) - all references to python2 have been replaced with python3 (notably shebangs) - fixed files not handled by 2to3 (notably the shell script) - several manual fixes - fixed issues reported by Python 3 that where not handled in Python 2 - replaced "async" with "async_" when needed (it's a reserved word from Python 3.7) - replaced zope's "implements" with @implementer decorator - temporary hack to handle data pickled in database, as str or bytes may be returned, to be checked later - fixed hash comparison for password - removed some code which is not needed anymore with Python 3 - deactivated some code which needs to be checked (notably certificate validation) - tested with jp, fixed reported issues until some basic commands worked - ported Primitivus (after porting dependencies like urwid satext) - more manual fixes
author Goffi <goffi@goffi.org>
date Tue, 13 Aug 2019 19:08:41 +0200
parents 003b8b4b56a7
children fee60f17ebac
comparison
equal deleted inserted replaced
3027:ff5bcb12ae60 3028:ab2696e34d29
1 #!/usr/bin/env python2 1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*- 2 # -*- coding: utf-8 -*-
3 3
4 # SAT: a jabber client 4 # SAT: a jabber client
5 # Copyright (C) 2009-2019 Jérôme Poisson (goffi@goffi.org) 5 # Copyright (C) 2009-2019 Jérôme Poisson (goffi@goffi.org)
6 6
54 54
55 ### TODO: add desciption in params 55 ### TODO: add desciption in params
56 56
57 # TODO: when priority is changed, a new presence stanza must be emitted 57 # TODO: when priority is changed, a new presence stanza must be emitted
58 # TODO: int type (Priority should be int instead of string) 58 # TODO: int type (Priority should be int instead of string)
59 default_xml = u""" 59 default_xml = """
60 <params> 60 <params>
61 <general> 61 <general>
62 </general> 62 </general>
63 <individual> 63 <individual>
64 <category name="General" label="%(category_general)s"> 64 <category name="General" label="%(category_general)s">
78 <param name="check_certificate" label="%(check_certificate_label)s" value="true" type="bool" security="4" /> 78 <param name="check_certificate" label="%(check_certificate_label)s" value="true" type="bool" security="4" />
79 </category> 79 </category>
80 </individual> 80 </individual>
81 </params> 81 </params>
82 """ % { 82 """ % {
83 u"category_general": D_(u"General"), 83 "category_general": D_("General"),
84 u"category_connection": D_(u"Connection"), 84 "category_connection": D_("Connection"),
85 u"history_param": C.HISTORY_LIMIT, 85 "history_param": C.HISTORY_LIMIT,
86 u"history_label": D_(u"Chat history limit"), 86 "history_label": D_("Chat history limit"),
87 u"show_offline_contacts": C.SHOW_OFFLINE_CONTACTS, 87 "show_offline_contacts": C.SHOW_OFFLINE_CONTACTS,
88 u"show_offline_contacts_label": D_(u"Show offline contacts"), 88 "show_offline_contacts_label": D_("Show offline contacts"),
89 u"show_empty_groups": C.SHOW_EMPTY_GROUPS, 89 "show_empty_groups": C.SHOW_EMPTY_GROUPS,
90 u"show_empty_groups_label": D_(u"Show empty groups"), 90 "show_empty_groups_label": D_("Show empty groups"),
91 u"force_server_param": C.FORCE_SERVER_PARAM, 91 "force_server_param": C.FORCE_SERVER_PARAM,
92 u"force_port_param": C.FORCE_PORT_PARAM, 92 "force_port_param": C.FORCE_PORT_PARAM,
93 u"new_account_label": D_(u"Register new account"), 93 "new_account_label": D_("Register new account"),
94 u"autoconnect_label": D_(u"Connect on frontend startup"), 94 "autoconnect_label": D_("Connect on frontend startup"),
95 u"autodisconnect_label": D_(u"Disconnect on frontend closure"), 95 "autodisconnect_label": D_("Disconnect on frontend closure"),
96 u"check_certificate_label": D_(u"Check certificate (don't uncheck if unsure)"), 96 "check_certificate_label": D_("Check certificate (don't uncheck if unsure)"),
97 } 97 }
98 98
99 def load_default_params(self): 99 def load_default_params(self):
100 self.dom = minidom.parseString(Params.default_xml.encode("utf-8")) 100 self.dom = minidom.parseString(Params.default_xml.encode("utf-8"))
101 101
156 """ 156 """
157 try: 157 try:
158 del self.params[profile] 158 del self.params[profile]
159 except KeyError: 159 except KeyError:
160 log.error( 160 log.error(
161 _(u"Trying to purge cache of a profile not in memory: [%s]") % profile 161 _("Trying to purge cache of a profile not in memory: [%s]") % profile
162 ) 162 )
163 163
164 def save_xml(self, filename): 164 def save_xml(self, filename):
165 """Save parameters template to xml file""" 165 """Save parameters template to xml file"""
166 with open(filename, "wb") as xml_file: 166 with open(filename, "wb") as xml_file:
236 elif profile_key == C.PROF_KEY_NONE: 236 elif profile_key == C.PROF_KEY_NONE:
237 raise exceptions.ProfileNotSetError 237 raise exceptions.ProfileNotSetError
238 elif return_profile_keys and profile_key in [C.PROF_KEY_ALL]: 238 elif return_profile_keys and profile_key in [C.PROF_KEY_ALL]:
239 return profile_key # this value must be managed by the caller 239 return profile_key # this value must be managed by the caller
240 if not self.storage.hasProfile(profile_key): 240 if not self.storage.hasProfile(profile_key):
241 log.error(_(u"Trying to access an unknown profile (%s)") % profile_key) 241 log.error(_("Trying to access an unknown profile (%s)") % profile_key)
242 raise exceptions.ProfileUnknownError(profile_key) 242 raise exceptions.ProfileUnknownError(profile_key)
243 return profile_key 243 return profile_key
244 244
245 def __get_unique_node(self, parent, tag, name): 245 def __get_unique_node(self, parent, tag, name):
246 """return node with given tag 246 """return node with given tag
292 continue 292 continue
293 node.setAttribute("app", app) 293 node.setAttribute("app", app)
294 if ( 294 if (
295 len(cat_node.childNodes) == to_remove_count 295 len(cat_node.childNodes) == to_remove_count
296 ): # remove empty category 296 ): # remove empty category
297 for __ in xrange(0, to_remove_count): 297 for __ in range(0, to_remove_count):
298 to_remove.pop() 298 to_remove.pop()
299 to_remove.append(cat_node) 299 to_remove.append(cat_node)
300 for node in to_remove: 300 for node in to_remove:
301 node.parentNode.removeChild(node) 301 node.parentNode.removeChild(node)
302 302
331 @param app: name of the frontend registering the parameters 331 @param app: name of the frontend registering the parameters
332 """ 332 """
333 if not app: 333 if not app:
334 log.warning( 334 log.warning(
335 _( 335 _(
336 u"Trying to register frontends parameters with no specified app: aborted" 336 "Trying to register frontends parameters with no specified app: aborted"
337 ) 337 )
338 ) 338 )
339 return 339 return
340 if not hasattr(self, "frontends_cache"): 340 if not hasattr(self, "frontends_cache"):
341 self.frontends_cache = [] 341 self.frontends_cache = []
342 if app in self.frontends_cache: 342 if app in self.frontends_cache:
343 log.debug( 343 log.debug(
344 _( 344 _(
345 u"Trying to register twice frontends parameters for %(app)s: aborted" 345 "Trying to register twice frontends parameters for %(app)s: aborted"
346 % {"app": app} 346 % {"app": app}
347 ) 347 )
348 ) 348 )
349 return 349 return
350 self.frontends_cache.append(app) 350 self.frontends_cache.append(app)
351 self.updateParams(xml, security_limit, app) 351 self.updateParams(xml, security_limit, app)
352 log.debug(u"Frontends parameters registered for %(app)s" % {"app": app}) 352 log.debug("Frontends parameters registered for %(app)s" % {"app": app})
353 353
354 def __default_ok(self, value, name, category): 354 def __default_ok(self, value, name, category):
355 # FIXME: will not work with individual parameters 355 # FIXME: will not work with individual parameters
356 self.setParam(name, value, category) 356 self.setParam(name, value, category)
357 357
358 def __default_ko(self, failure, name, category): 358 def __default_ko(self, failure, name, category):
359 log.error( 359 log.error(
360 _(u"Can't determine default value for [%(category)s/%(name)s]: %(reason)s") 360 _("Can't determine default value for [%(category)s/%(name)s]: %(reason)s")
361 % {"category": category, "name": name, "reason": str(failure.value)} 361 % {"category": category, "name": name, "reason": str(failure.value)}
362 ) 362 )
363 363
364 def setDefault(self, name, category, callback, errback=None): 364 def setDefault(self, name, category, callback, errback=None):
365 """Set default value of parameter 365 """Set default value of parameter
378 ) 378 )
379 node = self._getParamNode(name, category, "@ALL@") 379 node = self._getParamNode(name, category, "@ALL@")
380 if not node: 380 if not node:
381 log.error( 381 log.error(
382 _( 382 _(
383 u"Requested param [%(name)s] in category [%(category)s] doesn't exist !" 383 "Requested param [%(name)s] in category [%(category)s] doesn't exist !"
384 ) 384 )
385 % {"name": name, "category": category} 385 % {"name": name, "category": category}
386 ) 386 )
387 return 387 return
388 if node[1].getAttribute("default_cb") == "yes": 388 if node[1].getAttribute("default_cb") == "yes":
441 ) 441 )
442 return value_to_use 442 return value_to_use
443 if len(selected) == 0: 443 if len(selected) == 0:
444 log.error( 444 log.error(
445 _( 445 _(
446 u"Parameter (%(cat)s, %(param)s) of type list has no default option!" 446 "Parameter (%(cat)s, %(param)s) of type list has no default option!"
447 ) 447 )
448 % {"cat": cat, "param": param} 448 % {"cat": cat, "param": param}
449 ) 449 )
450 else: 450 else:
451 log.error( 451 log.error(
452 _( 452 _(
453 u"Parameter (%(cat)s, %(param)s) of type list has more than one default option!" 453 "Parameter (%(cat)s, %(param)s) of type list has more than one default option!"
454 ) 454 )
455 % {"cat": cat, "param": param} 455 % {"cat": cat, "param": param}
456 ) 456 )
457 raise exceptions.DataError 457 raise exceptions.DataError
458 elif node.getAttribute("type") == "jids_list": 458 elif node.getAttribute("type") == "jids_list":
466 for idx, value in enumerate(jids): 466 for idx, value in enumerate(jids):
467 try: 467 try:
468 jids[idx] = jid.JID(value) 468 jids[idx] = jid.JID(value)
469 except (RuntimeError, jid.InvalidFormat, AttributeError): 469 except (RuntimeError, jid.InvalidFormat, AttributeError):
470 log.warning( 470 log.warning(
471 u"Incorrect jid value found in jids list: [{}]".format(value) 471 "Incorrect jid value found in jids list: [{}]".format(value)
472 ) 472 )
473 to_delete.append(value) 473 to_delete.append(value)
474 for value in to_delete: 474 for value in to_delete:
475 jids.remove(value) 475 jids.remove(value)
476 return jids 476 return jids
562 # FIXME: security_limit is not managed here ! 562 # FIXME: security_limit is not managed here !
563 node = self._getParamNode(name, category) 563 node = self._getParamNode(name, category)
564 if not node: 564 if not node:
565 log.error( 565 log.error(
566 _( 566 _(
567 u"Requested param [%(name)s] in category [%(category)s] doesn't exist !" 567 "Requested param [%(name)s] in category [%(category)s] doesn't exist !"
568 ) 568 )
569 % {"name": name, "category": category} 569 % {"name": name, "category": category}
570 ) 570 )
571 raise exceptions.NotFound 571 raise exceptions.NotFound
572 572
628 """ 628 """
629 node = self._getParamNode(name, category) 629 node = self._getParamNode(name, category)
630 if not node: 630 if not node:
631 log.error( 631 log.error(
632 _( 632 _(
633 u"Requested param [%(name)s] in category [%(category)s] doesn't exist !" 633 "Requested param [%(name)s] in category [%(category)s] doesn't exist !"
634 ) 634 )
635 % {"name": name, "category": category} 635 % {"name": name, "category": category}
636 ) 636 )
637 raise ValueError("Requested param doesn't exist") 637 raise ValueError("Requested param doesn't exist")
638 638
639 if not self.checkSecurityLimit(node[1], security_limit): 639 if not self.checkSecurityLimit(node[1], security_limit):
640 log.warning( 640 log.warning(
641 _( 641 _(
642 u"Trying to get parameter '%(param)s' in category '%(cat)s' without authorization!!!" 642 "Trying to get parameter '%(param)s' in category '%(cat)s' without authorization!!!"
643 % {"param": name, "cat": category} 643 % {"param": name, "cat": category}
644 ) 644 )
645 ) 645 )
646 raise exceptions.PermissionError 646 raise exceptions.PermissionError
647 647
695 if category_node.getAttribute("name") == category: 695 if category_node.getAttribute("name") == category:
696 for param_node in category_node.getElementsByTagName("param"): 696 for param_node in category_node.getElementsByTagName("param"):
697 name = param_node.getAttribute("name") 697 name = param_node.getAttribute("name")
698 if not name: 698 if not name:
699 log.warning( 699 log.warning(
700 u"ignoring attribute without name: {}".format( 700 "ignoring attribute without name: {}".format(
701 param_node.toxml() 701 param_node.toxml()
702 ) 702 )
703 ) 703 )
704 continue 704 continue
705 d = self.asyncGetStringParamA( 705 d = self.asyncGetStringParamA(
848 RuntimeError, 848 RuntimeError,
849 jid.InvalidFormat, 849 jid.InvalidFormat,
850 AttributeError, 850 AttributeError,
851 ): 851 ):
852 log.warning( 852 log.warning(
853 u"Incorrect jid value found in jids list: [{}]".format( 853 "Incorrect jid value found in jids list: [{}]".format(
854 jid_ 854 jid_
855 ) 855 )
856 ) 856 )
857 else: 857 else:
858 jid_elt = prof_xml.createElement("jid") 858 jid_elt = prof_xml.createElement("jid")
980 """ 980 """
981 # FIXME: setParam should accept the right type for value, not only str ! 981 # FIXME: setParam should accept the right type for value, not only str !
982 if profile_key != C.PROF_KEY_NONE: 982 if profile_key != C.PROF_KEY_NONE:
983 profile = self.getProfileName(profile_key) 983 profile = self.getProfileName(profile_key)
984 if not profile: 984 if not profile:
985 log.error(_(u"Trying to set parameter for an unknown profile")) 985 log.error(_("Trying to set parameter for an unknown profile"))
986 raise exceptions.ProfileUnknownError(profile_key) 986 raise exceptions.ProfileUnknownError(profile_key)
987 987
988 node = self._getParamNode(name, category, "@ALL@") 988 node = self._getParamNode(name, category, "@ALL@")
989 if not node: 989 if not node:
990 log.error( 990 log.error(
991 _(u"Requesting an unknown parameter (%(category)s/%(name)s)") 991 _("Requesting an unknown parameter (%(category)s/%(name)s)")
992 % {"category": category, "name": name} 992 % {"category": category, "name": name}
993 ) 993 )
994 return defer.succeed(None) 994 return defer.succeed(None)
995 995
996 if not self.checkSecurityLimit(node[1], security_limit): 996 if not self.checkSecurityLimit(node[1], security_limit):
997 log.warning( 997 log.warning(
998 _( 998 _(
999 u"Trying to set parameter '%(param)s' in category '%(cat)s' without authorization!!!" 999 "Trying to set parameter '%(param)s' in category '%(cat)s' without authorization!!!"
1000 % {"param": name, "cat": category} 1000 % {"param": name, "cat": category}
1001 ) 1001 )
1002 ) 1002 )
1003 return defer.succeed(None) 1003 return defer.succeed(None)
1004 1004
1010 try: 1010 try:
1011 int(value) 1011 int(value)
1012 except ValueError: 1012 except ValueError:
1013 log.debug( 1013 log.debug(
1014 _( 1014 _(
1015 u"Trying to set parameter '%(param)s' in category '%(cat)s' with an non-integer value" 1015 "Trying to set parameter '%(param)s' in category '%(cat)s' with an non-integer value"
1016 % {"param": name, "cat": category} 1016 % {"param": name, "cat": category}
1017 ) 1017 )
1018 ) 1018 )
1019 return defer.succeed(None) 1019 return defer.succeed(None)
1020 if node[1].hasAttribute("constraint"): 1020 if node[1].hasAttribute("constraint"):
1049 1049
1050 assert node[0] == C.INDIVIDUAL 1050 assert node[0] == C.INDIVIDUAL
1051 assert profile_key != C.PROF_KEY_NONE 1051 assert profile_key != C.PROF_KEY_NONE
1052 1052
1053 if type_ == "button": 1053 if type_ == "button":
1054 log.debug(u"Clicked param button %s" % node.toxml()) 1054 log.debug("Clicked param button %s" % node.toxml())
1055 return defer.succeed(None) 1055 return defer.succeed(None)
1056 elif type_ == "password": 1056 elif type_ == "password":
1057 try: 1057 try:
1058 personal_key = self.host.memory.auth_sessions.profileGetUnique(profile)[ 1058 personal_key = self.host.memory.auth_sessions.profileGetUnique(profile)[
1059 C.MEMORY_CRYPTO_KEY 1059 C.MEMORY_CRYPTO_KEY