Mercurial > libervia-backend
comparison sat/plugins/plugin_misc_account.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 | 420897488080 |
children | 82eee2c383d9 |
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 plugin for account creation (experimental) | 4 # SAT plugin for account creation (experimental) |
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 |
24 from sat.core import exceptions | 24 from sat.core import exceptions |
25 from sat.tools import xml_tools | 25 from sat.tools import xml_tools |
26 from sat.memory.memory import Sessions | 26 from sat.memory.memory import Sessions |
27 from sat.memory.crypto import PasswordHasher | 27 from sat.memory.crypto import PasswordHasher |
28 from sat.core.constants import Const as C | 28 from sat.core.constants import Const as C |
29 import ConfigParser | 29 import configparser |
30 from twisted.internet import defer | 30 from twisted.internet import defer |
31 from twisted.python.failure import Failure | 31 from twisted.python.failure import Failure |
32 from twisted.words.protocols.jabber import jid | 32 from twisted.words.protocols.jabber import jid |
33 from sat.tools.common import email as sat_email | 33 from sat.tools.common import email as sat_email |
34 | 34 |
43 C.PI_PROTOCOLS: [], | 43 C.PI_PROTOCOLS: [], |
44 C.PI_DEPENDENCIES: ["XEP-0077"], | 44 C.PI_DEPENDENCIES: ["XEP-0077"], |
45 C.PI_RECOMMENDATIONS: ["GROUPBLOG"], | 45 C.PI_RECOMMENDATIONS: ["GROUPBLOG"], |
46 C.PI_MAIN: "MiscAccount", | 46 C.PI_MAIN: "MiscAccount", |
47 C.PI_HANDLER: "no", | 47 C.PI_HANDLER: "no", |
48 C.PI_DESCRIPTION: _(u"""SàT account creation"""), | 48 C.PI_DESCRIPTION: _("""SàT account creation"""), |
49 } | 49 } |
50 | 50 |
51 CONFIG_SECTION = "plugin account" | 51 CONFIG_SECTION = "plugin account" |
52 | 52 |
53 # You need do adapt the following consts to your server | 53 # You need do adapt the following consts to your server |
69 "new_account_domain": "", # use xmpp_domain if not found | 69 "new_account_domain": "", # use xmpp_domain if not found |
70 "reserved_list": ["libervia"], # profiles which can't be used | 70 "reserved_list": ["libervia"], # profiles which can't be used |
71 } | 71 } |
72 | 72 |
73 WELCOME_MSG = D_( | 73 WELCOME_MSG = D_( |
74 u"""Welcome to Libervia, the web interface of Salut à Toi. | 74 """Welcome to Libervia, the web interface of Salut à Toi. |
75 | 75 |
76 Your account on {domain} has been successfully created. | 76 Your account on {domain} has been successfully created. |
77 This is a demonstration version to show you the current status of the project. | 77 This is a demonstration version to show you the current status of the project. |
78 It is still under development, please keep it in mind! | 78 It is still under development, please keep it in mind! |
79 | 79 |
92 Salut à Toi association | 92 Salut à Toi association |
93 https://www.salut-a-toi.org | 93 https://www.salut-a-toi.org |
94 """ | 94 """ |
95 ) | 95 ) |
96 | 96 |
97 DEFAULT_DOMAIN = u"example.net" | 97 DEFAULT_DOMAIN = "example.net" |
98 | 98 |
99 | 99 |
100 class MiscAccount(object): | 100 class MiscAccount(object): |
101 """Account plugin: create a SàT + XMPP account, used by Libervia""" | 101 """Account plugin: create a SàT + XMPP account, used by Libervia""" |
102 | 102 |
103 # XXX: This plugin was initialy a Q&D one used for the demo. | 103 # XXX: This plugin was initialy a Q&D one used for the demo. |
104 # TODO: cleaning, separate email handling, more configuration/tests, fixes | 104 # TODO: cleaning, separate email handling, more configuration/tests, fixes |
105 | 105 |
106 def __init__(self, host): | 106 def __init__(self, host): |
107 log.info(_(u"Plugin Account initialization")) | 107 log.info(_("Plugin Account initialization")) |
108 self.host = host | 108 self.host = host |
109 host.bridge.addMethod( | 109 host.bridge.addMethod( |
110 "registerSatAccount", | 110 "registerSatAccount", |
111 ".plugin", | 111 ".plugin", |
112 in_sign="sss", | 112 in_sign="sss", |
113 out_sign="", | 113 out_sign="", |
114 method=self._registerAccount, | 114 method=self._registerAccount, |
115 async=True, | 115 async_=True, |
116 ) | 116 ) |
117 host.bridge.addMethod( | 117 host.bridge.addMethod( |
118 "getNewAccountDomain", | 118 "getNewAccountDomain", |
119 ".plugin", | 119 ".plugin", |
120 in_sign="", | 120 in_sign="", |
121 out_sign="s", | 121 out_sign="s", |
122 method=self.getNewAccountDomain, | 122 method=self.getNewAccountDomain, |
123 async=False, | 123 async_=False, |
124 ) | 124 ) |
125 host.bridge.addMethod( | 125 host.bridge.addMethod( |
126 "getAccountDialogUI", | 126 "getAccountDialogUI", |
127 ".plugin", | 127 ".plugin", |
128 in_sign="s", | 128 in_sign="s", |
129 out_sign="s", | 129 out_sign="s", |
130 method=self._getAccountDialogUI, | 130 method=self._getAccountDialogUI, |
131 async=False, | 131 async_=False, |
132 ) | 132 ) |
133 host.bridge.addMethod( | 133 host.bridge.addMethod( |
134 "asyncConnectWithXMPPCredentials", | 134 "asyncConnectWithXMPPCredentials", |
135 ".plugin", | 135 ".plugin", |
136 in_sign="ss", | 136 in_sign="ss", |
137 out_sign="b", | 137 out_sign="b", |
138 method=self.asyncConnectWithXMPPCredentials, | 138 method=self.asyncConnectWithXMPPCredentials, |
139 async=True, | 139 async_=True, |
140 ) | 140 ) |
141 | 141 |
142 self.fixEmailAdmins() | 142 self.fixEmailAdmins() |
143 self._sessions = Sessions() | 143 self._sessions = Sessions() |
144 | 144 |
173 """Handle deprecated config option "admin_email" to fix the admin emails list""" | 173 """Handle deprecated config option "admin_email" to fix the admin emails list""" |
174 admin_email = self.getConfig("admin_email") | 174 admin_email = self.getConfig("admin_email") |
175 if not admin_email: | 175 if not admin_email: |
176 return | 176 return |
177 log.warning( | 177 log.warning( |
178 u"admin_email parameter is deprecated, please use email_admins_list instead" | 178 "admin_email parameter is deprecated, please use email_admins_list instead" |
179 ) | 179 ) |
180 param_name = "email_admins_list" | 180 param_name = "email_admins_list" |
181 try: | 181 try: |
182 section = "" | 182 section = "" |
183 value = self.host.memory.getConfig(section, param_name, Exception) | 183 value = self.host.memory.getConfig(section, param_name, Exception) |
184 except (ConfigParser.NoOptionError, ConfigParser.NoSectionError): | 184 except (configparser.NoOptionError, configparser.NoSectionError): |
185 section = CONFIG_SECTION | 185 section = CONFIG_SECTION |
186 value = self.host.memory.getConfig( | 186 value = self.host.memory.getConfig( |
187 section, param_name, default_conf[param_name] | 187 section, param_name, default_conf[param_name] |
188 ) | 188 ) |
189 | 189 |
196 # XXX: email_ parameters were first in [plugin account] section | 196 # XXX: email_ parameters were first in [plugin account] section |
197 # but as it make more sense to have them in common with other plugins, | 197 # but as it make more sense to have them in common with other plugins, |
198 # they can now be in [DEFAULT] section | 198 # they can now be in [DEFAULT] section |
199 try: | 199 try: |
200 value = self.host.memory.getConfig(None, name, Exception) | 200 value = self.host.memory.getConfig(None, name, Exception) |
201 except (ConfigParser.NoOptionError, ConfigParser.NoSectionError): | 201 except (configparser.NoOptionError, configparser.NoSectionError): |
202 pass | 202 pass |
203 else: | 203 else: |
204 return value | 204 return value |
205 | 205 |
206 if section == CONFIG_SECTION: | 206 if section == CONFIG_SECTION: |
261 """ | 261 """ |
262 if jid_s: | 262 if jid_s: |
263 d = defer.succeed(None) | 263 d = defer.succeed(None) |
264 jid_ = jid.JID(jid_s) | 264 jid_ = jid.JID(jid_s) |
265 else: | 265 else: |
266 jid_s = profile + u"@" + self.getNewAccountDomain() | 266 jid_s = profile + "@" + self.getNewAccountDomain() |
267 jid_ = jid.JID(jid_s) | 267 jid_ = jid.JID(jid_s) |
268 d = self.host.plugins["XEP-0077"].registerNewAccount(jid_, password) | 268 d = self.host.plugins["XEP-0077"].registerNewAccount(jid_, password) |
269 | 269 |
270 def setParams(__): | 270 def setParams(__): |
271 self.host.memory.setParam( | 271 self.host.memory.setParam( |
287 return d | 287 return d |
288 | 288 |
289 def _sendEmailEb(self, failure_, email): | 289 def _sendEmailEb(self, failure_, email): |
290 # TODO: return error code to user | 290 # TODO: return error code to user |
291 log.error( | 291 log.error( |
292 _(u"Failed to send account creation confirmation to {email}: {msg}").format( | 292 _("Failed to send account creation confirmation to {email}: {msg}").format( |
293 email=email, msg=failure_ | 293 email=email, msg=failure_ |
294 ) | 294 ) |
295 ) | 295 ) |
296 | 296 |
297 def sendEmails(self, email, profile): | 297 def sendEmails(self, email, profile): |
301 | 301 |
302 # email to the administrators | 302 # email to the administrators |
303 admins_emails = self.getConfig("email_admins_list") | 303 admins_emails = self.getConfig("email_admins_list") |
304 if not admins_emails: | 304 if not admins_emails: |
305 log.warning( | 305 log.warning( |
306 u"No known admin email, we can't send email to administrator(s).\nPlease fill email_admins_list parameter" | 306 "No known admin email, we can't send email to administrator(s).\nPlease fill email_admins_list parameter" |
307 ) | 307 ) |
308 d_admin = defer.fail(exceptions.DataError("no admin email")) | 308 d_admin = defer.fail(exceptions.DataError("no admin email")) |
309 else: | 309 else: |
310 subject = _(u"New Libervia account created") | 310 subject = _("New Libervia account created") |
311 body = u"""New account created: {profile} [{email}]""".format( | 311 body = """New account created: {profile} [{email}]""".format( |
312 profile=profile, | 312 profile=profile, |
313 # there is no email when an existing XMPP account is used | 313 # there is no email when an existing XMPP account is used |
314 email=email or u"<no email>", | 314 email=email or "<no email>", |
315 ) | 315 ) |
316 d_admin = sat_email.sendEmail(self.host, admins_emails, subject, body) | 316 d_admin = sat_email.sendEmail(self.host, admins_emails, subject, body) |
317 | 317 |
318 admins_emails_txt = u", ".join([u"<" + addr + u">" for addr in admins_emails]) | 318 admins_emails_txt = ", ".join(["<" + addr + ">" for addr in admins_emails]) |
319 d_admin.addCallbacks( | 319 d_admin.addCallbacks( |
320 lambda __: log.debug( | 320 lambda __: log.debug( |
321 u"Account creation notification sent to admin(s) {}".format( | 321 "Account creation notification sent to admin(s) {}".format( |
322 admins_emails_txt | 322 admins_emails_txt |
323 ) | 323 ) |
324 ), | 324 ), |
325 lambda __: log.error( | 325 lambda __: log.error( |
326 u"Failed to send account creation notification to admin {}".format( | 326 "Failed to send account creation notification to admin {}".format( |
327 admins_emails_txt | 327 admins_emails_txt |
328 ) | 328 ) |
329 ), | 329 ), |
330 ) | 330 ) |
331 if not email: | 331 if not email: |
332 # TODO: if use register with an existing account, an XMPP message should be sent | 332 # TODO: if use register with an existing account, an XMPP message should be sent |
333 return d_admin | 333 return d_admin |
334 | 334 |
335 jid_s = self.host.memory.getParamA( | 335 jid_s = self.host.memory.getParamA( |
336 u"JabberID", u"Connection", profile_key=profile | 336 "JabberID", "Connection", profile_key=profile |
337 ) | 337 ) |
338 subject = _(u"Your Libervia account has been created") | 338 subject = _("Your Libervia account has been created") |
339 body = _(WELCOME_MSG).format(profile=profile, jid=jid_s, domain=domain) | 339 body = _(WELCOME_MSG).format(profile=profile, jid=jid_s, domain=domain) |
340 | 340 |
341 # XXX: this will not fail when the email address doesn't exist | 341 # XXX: this will not fail when the email address doesn't exist |
342 # FIXME: check email reception to validate email given by the user | 342 # FIXME: check email reception to validate email given by the user |
343 # FIXME: delete the profile if the email could not been sent? | 343 # FIXME: delete the profile if the email could not been sent? |
344 d_user = sat_email.sendEmail(self.host, [email], subject, body) | 344 d_user = sat_email.sendEmail(self.host, [email], subject, body) |
345 d_user.addCallbacks( | 345 d_user.addCallbacks( |
346 lambda __: log.debug( | 346 lambda __: log.debug( |
347 u"Account creation confirmation sent to <{}>".format(email) | 347 "Account creation confirmation sent to <{}>".format(email) |
348 ), | 348 ), |
349 self._sendEmailEb, | 349 self._sendEmailEb, |
350 ) | 350 ) |
351 return defer.DeferredList([d_user, d_admin]) | 351 return defer.DeferredList([d_user, d_admin]) |
352 | 352 |
357 "xmpp_domain", None | 357 "xmpp_domain", None |
358 ) | 358 ) |
359 if not domain: | 359 if not domain: |
360 log.warning( | 360 log.warning( |
361 _( | 361 _( |
362 u'xmpp_domain needs to be set in sat.conf. Using "{default}" meanwhile' | 362 'xmpp_domain needs to be set in sat.conf. Using "{default}" meanwhile' |
363 ).format(default=DEFAULT_DOMAIN) | 363 ).format(default=DEFAULT_DOMAIN) |
364 ) | 364 ) |
365 return DEFAULT_DOMAIN | 365 return DEFAULT_DOMAIN |
366 return domain | 366 return domain |
367 | 367 |