diff src/plugins/plugin_misc_account.py @ 730:32bbabe809da

plugin account: configuration constants can be overriden in sat.conf (section "plugin account") + better deferred management in email sending
author Goffi <goffi@goffi.org>
date Fri, 13 Dec 2013 17:15:57 +0100
parents 712e3782af12
children ffc3ddcdaf48
line wrap: on
line diff
--- a/src/plugins/plugin_misc_account.py	Thu Dec 12 01:06:19 2013 +0100
+++ b/src/plugins/plugin_misc_account.py	Fri Dec 13 17:15:57 2013 +0100
@@ -1,7 +1,7 @@
 #!/usr/bin/python
 # -*- coding: utf-8 -*-
 
-# SAT plugin for parrot mode (experimental)
+# SAT plugin for account creation (experimental)
 # Copyright (C) 2009, 2010, 2011, 2012, 2013 Jérôme Poisson (goffi@goffi.org)
 
 # This program is free software: you can redistribute it and/or modify
@@ -37,17 +37,22 @@
     "description": _(u"""SàT account creation""")
 }
 
-#You need do adapt the following consts to your server
-_REG_EMAIL_FROM = "NOREPLY@example.net"
-_REG_EMAIL_SERVER = "localhost"
-_REG_ADMIN_EMAIL = "admin@example.net"
-_NEW_ACCOUNT_SERVER = "localhost"
-_NEW_ACCOUNT_DOMAIN = "example.net"
-_NEW_ACCOUNT_RESOURCE = "libervia"
-_PROSODY_PATH = None  # prosody path (where prosodyctl will be executed from), or None to automaticaly find it
-_PROSODYCTL = "prosodyctl"
+CONFIG_SECTION = "plugin account"
+
+# You need do adapt the following consts to your server
+# all theses values (key=option name, value=default) can (and should) be overriden in sat.conf
+# in section CONFIG_SECTION
 
-RESERVED = ['libervia']
+default_conf = {"email_from": "NOREPLY@example.net",
+                "email_server": "localhost",
+                "admin_email": "admin@example.net",
+                "new_account_server": "localhost",
+                "new_account_domain": "example.net",
+                "new_account_resource": "libervia",
+                "prosody_path": None, # prosody path (where prosodyctl will be executed from), or None to automaticaly find it
+                "prosodyctl": "prosodyctl",
+                "reserved_list": ['libervia'] # profiles which can't be used
+               }
 
 
 class ProsodyRegisterProtocol(protocol.ProcessProtocol):
@@ -81,21 +86,24 @@
     """Account plugin: create a SàT + Prosody account, used by Libervia"""
     #XXX: This plugin is a Q&D one used for the demo. Something more generic (and not
     #     only focused on Prosody) is planed
-    _prosody_path = _PROSODY_PATH or ''
 
     def __init__(self, host):
         info(_(u"Plugin Account initialization"))
         self.host = host
         host.bridge.addMethod("registerSatAccount", ".plugin", in_sign='sss', out_sign='', method=self._registerAccount, async=True)
         host.bridge.addMethod("getNewAccountDomain", ".plugin", in_sign='', out_sign='s', method=self._getNewAccountDomain, async=False)
-        if not self._prosody_path:
-            paths = which(_PROSODYCTL)
+        self._prosody_path = self.getConfig('prosody_path')
+        if self._prosody_path is None:
+            paths = which(self.getConfig('prosodyctl'))
             if not paths:
-                error(_("Can't find %s") % (_PROSODYCTL, ))
+                error(_("Can't find %s") % (self.getConfig('prosodyctl'), ))
             else:
                 self._prosody_path = dirname(paths[0])
                 info(_('Prosody path found: %s') % (self._prosody_path, ))
 
+    def getConfig(self, name):
+        return self.host.memory.getConfig(CONFIG_SECTION, name) or default_conf[name]
+
     def _registerAccount(self, email, password, profile):
 
         """
@@ -109,7 +117,7 @@
         if not email or not password or not profile:
             raise exceptions.DataError
 
-        if profile.lower() in RESERVED:
+        if profile.lower() in self.getConfig('reserved_list'):
             return defer.fail(Failure(u'CONFLICT'))
 
         d = self.host.memory.asyncCreateProfile(profile)
@@ -119,9 +127,9 @@
     def _profileRegistered(self, result, email, password, profile):
 
         #FIXME: values must be in a config file instead of hardcoded
-        self.host.memory.setParam("JabberID", "%s@%s/%s" % (profile, _NEW_ACCOUNT_DOMAIN, _NEW_ACCOUNT_RESOURCE),
+        self.host.memory.setParam("JabberID", "%s@%s/%s" % (profile, self.getConfig('new_account_domain'), self.getConfig('new_account_resource')),
                                   "Connection", profile_key=profile)
-        self.host.memory.setParam("Server", _NEW_ACCOUNT_SERVER,
+        self.host.memory.setParam("Server", self.getConfig('new_account_server'),
                                   "Connection", profile_key=profile)
         self.host.memory.setParam("Password", password,
                                   "Connection", profile_key=profile)
@@ -131,17 +139,18 @@
         #     and just change the password if the account already exists
         d = defer.Deferred()
         prosody_reg = ProsodyRegisterProtocol(password, d)
-        prosody_exe = join(self._prosody_path, _PROSODYCTL)
-        reactor.spawnProcess(prosody_reg, prosody_exe, [prosody_exe, 'adduser', "%s@%s" % (profile, _NEW_ACCOUNT_DOMAIN)], path=self._prosody_path)
+        prosody_exe = join(self._prosody_path, self.getConfig('prosodyctl'))
+        reactor.spawnProcess(prosody_reg, prosody_exe, [prosody_exe, 'adduser', "%s@%s" % (profile, self.getConfig('new_account_domain'))], path=self._prosody_path)
 
-        d.addCallback(self._accountCreated, profile, email, password)
+        d.addCallback(self._sendEmails, profile, email, password)
+        d.addCallback(lambda ignore: None)
         return d
 
-    def _accountCreated(self, result, login, email, password):
+    def _sendEmails(self, result, login, email, password):
         #time to send the email
 
-        _email_host = _REG_EMAIL_SERVER
-        _email_from = _REG_EMAIL_FROM
+        _email_host = self.getConfig('email_server')
+        _email_from = self.getConfig("email_from")
 
         def email_ok(ignore):
             print ("Account creation email sent to %s" % email)
@@ -168,26 +177,27 @@
 Any feedback welcome
 
 Cheers
-Goffi""" % {'login': login, 'password': password, 'jid': "%s@%s" % (login, _NEW_ACCOUNT_DOMAIN)}).encode('utf-8')
+Goffi""" % {'login': login, 'password': password, 'jid': "%s@%s" % (login, self.getConfig('new_account_domain'))}).encode('utf-8')
         msg = MIMEText(body, 'plain', 'UTF-8')
         msg['Subject'] = 'Libervia account created'
         msg['From'] = _email_from
         msg['To'] = email
 
-        d = sendmail(_email_host, _email_from, email, msg.as_string())
-        d.addCallbacks(email_ok, email_ko)
+        d_user = sendmail(_email_host, _email_from, email, msg.as_string())
+        d_user.addCallbacks(email_ok, email_ko)
+
         #email to the administrator
-
         body = (u"""New account created: %(login)s [%(email)s]""" % {'login': login, 'email': email}).encode('utf-8')
         msg = MIMEText(body, 'plain', 'UTF-8')
         msg['Subject'] = 'Libervia new account created'
         msg['From'] = _email_from
-        msg['To'] = _REG_ADMIN_EMAIL
+        msg['To'] = self.getConfig('admin_email')
 
-        d = sendmail(_email_host, _email_from, _REG_ADMIN_EMAIL, msg.as_string())
-        d.addCallbacks(email_ok, email_ko)
+        d_admin = sendmail(_email_host, _email_from, self.getConfig('admin_email'), msg.as_string())
+        d_admin.addCallbacks(email_ok, email_ko)
+        return defer.DeferredList([d_user, d_admin])
 
     def _getNewAccountDomain(self):
         """@return: the domain that will be set to new account"""
-        return _NEW_ACCOUNT_DOMAIN
+        return self.getConfig('new_account_domain')