diff --git a/orchestra/contrib/bills/actions.py b/orchestra/contrib/bills/actions.py index 8e358348..d3f03862 100644 --- a/orchestra/contrib/bills/actions.py +++ b/orchestra/contrib/bills/actions.py @@ -98,7 +98,7 @@ close_bills.url_name = 'close' def send_bills(modeladmin, request, queryset): for bill in queryset: if not validate_contact(request, bill): - return + return False num = 0 for bill in queryset: bill.send() @@ -131,10 +131,13 @@ download_bills.url_name = 'download' def close_send_download_bills(modeladmin, request, queryset): - close_bills(modeladmin, request, queryset) + response = close_bills(modeladmin, request, queryset) if request.POST.get('post') == 'generic_confirmation': - send_bills(modeladmin, request, queryset) + response = send_bills(modeladmin, request, queryset) + if response is False: + return return download_bills(modeladmin, request, queryset) + return response close_send_download_bills.verbose_name = _("C.S.D.") close_send_download_bills.url_name = 'close-send-download' close_send_download_bills.help_text = _("Close, send and download bills in one shot.") diff --git a/orchestra/contrib/orchestration/methods.py b/orchestra/contrib/orchestration/methods.py index c51e372b..a0786a0c 100644 --- a/orchestra/contrib/orchestration/methods.py +++ b/orchestra/contrib/orchestration/methods.py @@ -1,8 +1,9 @@ -import json +import inspect import logging import socket import sys import select +import textwrap from celery.datastructures import ExceptionInfo @@ -147,11 +148,14 @@ def SSH(*args, **kwargs): def Python(backend, log, server, cmds, async=False): - script = [ str(cmd.func.__name__) + str(cmd.args) for cmd in cmds ] - script = json.dumps(script, indent=4).replace('"', '') + script = '' + for cmd in cmds: + script += '# %s\n' % (str(cmd.func.__name__) + str(cmd.args)) + script += textwrap.dedent(''.join(inspect.getsourcelines(cmd.func)[0])) log.state = log.STARTED log.script = '\n'.join((log.script, script)) log.save(update_fields=('script', 'state', 'updated_at')) + stdout = '' try: for cmd in cmds: with CaptureStdout() as stdout: @@ -163,6 +167,7 @@ def Python(backend, log, server, cmds, async=False): except: log.exit_code = 1 log.state = log.FAILURE + log.stdout = '\n'.join(stdout) log.traceback = ExceptionInfo(sys.exc_info()).traceback logger.error('Exception while executing %s on %s' % (backend, server)) else: diff --git a/orchestra/contrib/orders/admin.py b/orchestra/contrib/orders/admin.py index 171aa60d..a966295a 100644 --- a/orchestra/contrib/orders/admin.py +++ b/orchestra/contrib/orders/admin.py @@ -77,7 +77,9 @@ class OrderAdmin(AccountAdminMixin, ExtendedModelAdmin): red = False human = escape(naturaldate(billed_until)) if billed_until: - if order.service.billing_period == order.service.NEVER: + if order.cancelled_on and order.cancelled_on <= billed_until: + pass + elif order.service.billing_period == order.service.NEVER: human = _("Forever") elif order.service.payment_style == order.service.POSTPAY: boundary = order.service.handler.get_billing_point(order) diff --git a/orchestra/contrib/saas/backends/phplist.py b/orchestra/contrib/saas/backends/phplist.py index 62b8a39b..2e7215af 100644 --- a/orchestra/contrib/saas/backends/phplist.py +++ b/orchestra/contrib/saas/backends/phplist.py @@ -5,6 +5,8 @@ from django.utils.translation import ugettext_lazy as _ from orchestra.contrib.orchestration import ServiceController +from .. import settings + class PhpListSaaSBackend(ServiceController): """ @@ -21,8 +23,9 @@ class PhpListSaaSBackend(ServiceController): serialize = True def _save(self, saas, server): - admin_link = 'http://%s/admin/' % saas.get_site_domain() - admin_content = requests.get(admin_link).content.decode('utf8') + admin_link = 'https://%s/admin/' % saas.get_site_domain() + print('admin_link:', admin_link) + admin_content = requests.get(admin_link, verify=settings.SAAS_PHPLIST_VERIFY_SSL).content.decode('utf8') if admin_content.startswith('Cannot connect to Database'): raise RuntimeError("Database is not yet configured") install = re.search(r'([^"]+firstinstall[^"]+)', admin_content) @@ -37,7 +40,7 @@ class PhpListSaaSBackend(ServiceController): 'adminemail': saas.account.username, 'adminpassword': saas.password, } - response = requests.post(install_link, data=post) + response = requests.post(install_link, data=post, verify=settings.SAAS_PHPLIST_VERIFY_SSL) print(response.content.decode('utf8')) if response.status_code != 200: raise RuntimeError("Bad status code %i" % response.status_code) diff --git a/orchestra/contrib/saas/services/phplist.py b/orchestra/contrib/saas/services/phplist.py index 412729d4..24cf2c92 100644 --- a/orchestra/contrib/saas/services/phplist.py +++ b/orchestra/contrib/saas/services/phplist.py @@ -63,6 +63,11 @@ class PHPListService(SoftwareService): super(PHPListService, self).validate() create = not self.instance.pk if create: + db_user = self.get_db_user() + try: + DatabaseUser.objects.get(username=db_user) + except DatabaseUser.DoesNotExist: + raise ValidationError(_("Global database user for PHPList '%s' does not exists.")) account = self.get_account() db = Database(name=self.get_db_name(), account=account) try: diff --git a/orchestra/contrib/saas/settings.py b/orchestra/contrib/saas/settings.py index fd0599c2..263d2ac6 100644 --- a/orchestra/contrib/saas/settings.py +++ b/orchestra/contrib/saas/settings.py @@ -80,13 +80,18 @@ SAAS_PHPLIST_DB_NAME = Setting('SAAS_PHPLIST_DB_NAME', 'phplist_mu', ) - SAAS_PHPLIST_BASE_DOMAIN = Setting('SAAS_PHPLIST_BASE_DOMAIN', 'lists.{}'.format(ORCHESTRA_BASE_DOMAIN), help_text="Uses ORCHESTRA_BASE_DOMAIN by default.", ) +SAAS_PHPLIST_VERIFY_SSL = Setting('SAAS_PHPLIST_VERIFY_SSL', + True, + help_text="Verify SSL certificate on the HTTP requests performed by the backend.", +) + + SAAS_SEAFILE_DOMAIN = Setting('SAAS_SEAFILE_DOMAIN', 'seafile.{}'.format(ORCHESTRA_BASE_DOMAIN), help_text="Uses ORCHESTRA_BASE_DOMAIN by default.",