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.",