Random fixes
This commit is contained in:
parent
17739129d3
commit
cc4ecee4dd
|
@ -38,8 +38,6 @@ Django-orchestra can be installed on any Linux system, however it is **strongly
|
||||||
```bash
|
```bash
|
||||||
sudo apt-get install python3-psycopg2 postgresql
|
sudo apt-get install python3-psycopg2 postgresql
|
||||||
sudo python3 manage.py setuppostgres --db_password <password>
|
sudo python3 manage.py setuppostgres --db_password <password>
|
||||||
# admin_tools needs accounts and does not have migrations
|
|
||||||
python3 manage.py migrate accounts
|
|
||||||
python3 manage.py migrate
|
python3 manage.py migrate
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,6 @@ pip3 install -r \
|
||||||
|
|
||||||
# Create a new Orchestra site
|
# Create a new Orchestra site
|
||||||
orchestra-admin startproject panel
|
orchestra-admin startproject panel
|
||||||
python3 panel/manage.py migrate accounts
|
|
||||||
python3 panel/manage.py migrate
|
python3 panel/manage.py migrate
|
||||||
python3 panel/manage.py runserver
|
python3 panel/manage.py runserver
|
||||||
|
|
||||||
|
|
4
TODO.md
4
TODO.md
|
@ -57,7 +57,7 @@
|
||||||
|
|
||||||
* print open invoices as proforma?
|
* print open invoices as proforma?
|
||||||
|
|
||||||
* env ORCHESTRA_MASTER_SERVER='test1.orchestra.lan' ORCHESTRA_SECOND_SERVER='test2.orchestra.lan' ORCHESTRA_SLAVE_SERVER='test3.orchestra.lan' python manage.py test orchestra.apps.domains.tests.functional_tests.tests:AdminBind9BackendDomainTest --nologcapture
|
* env ORCHESTRA_MASTER_SERVER='test1.orchestra.lan' ORCHESTRA_SECOND_SERVER='test2.orchestra.lan' ORCHESTRA_SLAVE_SERVER='test3.orchestra.lan' python3 manage.py test orchestra.contrib.domains.tests.functional_tests.tests:AdminBind9BackendDomainTest --nologcapture
|
||||||
|
|
||||||
* ForeignKey.swappable
|
* ForeignKey.swappable
|
||||||
* Field.editable
|
* Field.editable
|
||||||
|
@ -360,3 +360,5 @@ resorce monitoring more efficient, less mem an better queries for calc current d
|
||||||
# Tests can not run because django.db.utils.ProgrammingError: relation "accounts_account" does not exist
|
# Tests can not run because django.db.utils.ProgrammingError: relation "accounts_account" does not exist
|
||||||
|
|
||||||
# autoresponses on mailboxes, not addresses or remove them
|
# autoresponses on mailboxes, not addresses or remove them
|
||||||
|
|
||||||
|
# Async particular actions?
|
||||||
|
|
|
@ -5,10 +5,12 @@ from django.contrib.contenttypes.models import ContentType
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
from orchestra.contrib.systemusers.models import SystemUser
|
from orchestra.contrib.systemusers.models import SystemUser
|
||||||
|
from orchestra.contrib.plans.models import Plan
|
||||||
|
from orchestra.utils.python import cmp_to_key
|
||||||
from orchestra.utils.tests import BaseTestCase
|
from orchestra.utils.tests import BaseTestCase
|
||||||
|
|
||||||
from .. import helpers
|
from .. import helpers
|
||||||
from ..models import Service, Plan
|
from ..models import Service
|
||||||
|
|
||||||
|
|
||||||
class Order(object):
|
class Order(object):
|
||||||
|
@ -40,7 +42,7 @@ class HandlerTests(BaseTestCase):
|
||||||
is_fee=False,
|
is_fee=False,
|
||||||
metric='',
|
metric='',
|
||||||
pricing_period=Service.NEVER,
|
pricing_period=Service.NEVER,
|
||||||
rate_algorithm='STEP_PRICE',
|
rate_algorithm='orchestra.contrib.plans.ratings.step_price',
|
||||||
on_cancel=Service.DISCOUNT,
|
on_cancel=Service.DISCOUNT,
|
||||||
payment_style=Service.PREPAY,
|
payment_style=Service.PREPAY,
|
||||||
tax=0,
|
tax=0,
|
||||||
|
@ -144,7 +146,7 @@ class HandlerTests(BaseTestCase):
|
||||||
order6 = Order(
|
order6 = Order(
|
||||||
registered_on=now+datetime.timedelta(days=8))
|
registered_on=now+datetime.timedelta(days=8))
|
||||||
orders = [order3, order, order1, order2, order4, order5, order6]
|
orders = [order3, order, order1, order2, order4, order5, order6]
|
||||||
self.assertEqual(orders, sorted(orders, cmp=helpers.cmp_billed_until_or_registered_on))
|
self.assertEqual(orders, sorted(orders, key=cmp_to_key(helpers.cmp_billed_until_or_registered_on)))
|
||||||
|
|
||||||
def test_compensation(self):
|
def test_compensation(self):
|
||||||
now = timezone.now().date()
|
now = timezone.now().date()
|
||||||
|
@ -192,7 +194,7 @@ class HandlerTests(BaseTestCase):
|
||||||
[now+datetime.timedelta(days=100), now+datetime.timedelta(days=102), order],
|
[now+datetime.timedelta(days=100), now+datetime.timedelta(days=102), order],
|
||||||
])
|
])
|
||||||
porders = [order3, order, order1, order2, order4, order5, order6]
|
porders = [order3, order, order1, order2, order4, order5, order6]
|
||||||
porders = sorted(porders, cmp=helpers.cmp_billed_until_or_registered_on)
|
porders = sorted(porders, key=cmp_to_key(helpers.cmp_billed_until_or_registered_on))
|
||||||
compensations = []
|
compensations = []
|
||||||
receivers = []
|
receivers = []
|
||||||
for order in porders:
|
for order in porders:
|
||||||
|
@ -223,10 +225,19 @@ class HandlerTests(BaseTestCase):
|
||||||
results = service.get_rates(account, cache=False)
|
results = service.get_rates(account, cache=False)
|
||||||
results = service.rate_method(results, 30)
|
results = service.rate_method(results, 30)
|
||||||
rates = [
|
rates = [
|
||||||
{'price': decimal.Decimal('0.00'), 'quantity': 2},
|
{
|
||||||
{'price': decimal.Decimal('10.00'), 'quantity': 1},
|
'price': decimal.Decimal('0.00'),
|
||||||
{'price': decimal.Decimal('9.00'), 'quantity': 6},
|
'quantity': 2
|
||||||
{'price': decimal.Decimal('1.00'), 'quantity': 21}
|
}, {
|
||||||
|
'price': decimal.Decimal('10.00'),
|
||||||
|
'quantity': 1
|
||||||
|
}, {
|
||||||
|
'price': decimal.Decimal('9.00'),
|
||||||
|
'quantity': 6
|
||||||
|
}, {
|
||||||
|
'price': decimal.Decimal('1.00'),
|
||||||
|
'quantity': 21
|
||||||
|
}
|
||||||
]
|
]
|
||||||
for rate, result in zip(rates, results):
|
for rate, result in zip(rates, results):
|
||||||
self.assertEqual(rate['price'], result.price)
|
self.assertEqual(rate['price'], result.price)
|
||||||
|
@ -280,7 +291,7 @@ class HandlerTests(BaseTestCase):
|
||||||
self.assertEqual(rate['price'], result.price)
|
self.assertEqual(rate['price'], result.price)
|
||||||
self.assertEqual(rate['quantity'], result.quantity)
|
self.assertEqual(rate['quantity'], result.quantity)
|
||||||
|
|
||||||
service.rate_algorithm = service.MATCH_PRICE
|
service.rate_algorithm = 'orchestra.contrib.plans.ratings.match_price'
|
||||||
service.save()
|
service.save()
|
||||||
results = service.get_rates(account, cache=False)
|
results = service.get_rates(account, cache=False)
|
||||||
results = service.rate_method(results, 30)
|
results = service.rate_method(results, 30)
|
||||||
|
@ -313,9 +324,16 @@ class HandlerTests(BaseTestCase):
|
||||||
results = service.get_rates(account, cache=False)
|
results = service.get_rates(account, cache=False)
|
||||||
results = service.rate_method(results, 30)
|
results = service.rate_method(results, 30)
|
||||||
rates = [
|
rates = [
|
||||||
{'price': decimal.Decimal('10.00'), 'quantity': 3},
|
{
|
||||||
{'price': decimal.Decimal('9.00'), 'quantity': 6},
|
'price': decimal.Decimal('10.00'),
|
||||||
{'price': decimal.Decimal('1.00'), 'quantity': 21}
|
'quantity': 3
|
||||||
|
}, {
|
||||||
|
'price': decimal.Decimal('9.00'),
|
||||||
|
'quantity': 6
|
||||||
|
}, {
|
||||||
|
'price': decimal.Decimal('1.00'),
|
||||||
|
'quantity': 21
|
||||||
|
}
|
||||||
]
|
]
|
||||||
for rate, result in zip(rates, results):
|
for rate, result in zip(rates, results):
|
||||||
self.assertEqual(rate['price'], result.price)
|
self.assertEqual(rate['price'], result.price)
|
||||||
|
|
|
@ -32,9 +32,16 @@ class UNIXUserBackend(ServiceController):
|
||||||
# TODO userd add will fail if %(user)s group already exists
|
# TODO userd add will fail if %(user)s group already exists
|
||||||
self.append(textwrap.dedent("""
|
self.append(textwrap.dedent("""
|
||||||
if [[ $( id %(user)s ) ]]; then
|
if [[ $( id %(user)s ) ]]; then
|
||||||
usermod %(user)s --password '%(password)s' --shell %(shell)s %(groups_arg)s
|
usermod %(user)s --home %(home)s --password '%(password)s' --shell %(shell)s %(groups_arg)s
|
||||||
else
|
else
|
||||||
useradd %(user)s --home %(home)s --password '%(password)s' --shell %(shell)s %(groups_arg)s
|
useradd %(user)s --home %(home)s --password '%(password)s' --shell %(shell)s %(groups_arg)s || {
|
||||||
|
# User is logged in, kill and retry
|
||||||
|
if [[ $? -eq 8 ]]; then
|
||||||
|
pkill -u %(user)s; sleep 2
|
||||||
|
pkill -9 -u %(user)s; sleep 1
|
||||||
|
useradd %(user)s --home %(home)s --password '%(password)s' --shell %(shell)s %(groups_arg)s
|
||||||
|
fi
|
||||||
|
}
|
||||||
fi
|
fi
|
||||||
mkdir -p %(base_home)s
|
mkdir -p %(base_home)s
|
||||||
chmod 750 %(base_home)s
|
chmod 750 %(base_home)s
|
||||||
|
@ -43,7 +50,9 @@ class UNIXUserBackend(ServiceController):
|
||||||
if context['home'] != context['base_home']:
|
if context['home'] != context['base_home']:
|
||||||
self.append(textwrap.dedent("""
|
self.append(textwrap.dedent("""
|
||||||
if [[ $(mount | grep "^$(df %(home)s|grep '^/')\s" | grep acl) ]]; then
|
if [[ $(mount | grep "^$(df %(home)s|grep '^/')\s" | grep acl) ]]; then
|
||||||
|
# Accountn group as the owner
|
||||||
chown %(mainuser)s:%(mainuser)s %(home)s
|
chown %(mainuser)s:%(mainuser)s %(home)s
|
||||||
|
chmod g+s %(home)s
|
||||||
# Home access
|
# Home access
|
||||||
setfacl -m u:%(user)s:--x '%(mainuser_home)s'
|
setfacl -m u:%(user)s:--x '%(mainuser_home)s'
|
||||||
# Grant perms to future files within the directory
|
# Grant perms to future files within the directory
|
||||||
|
|
|
@ -33,44 +33,46 @@ class SystemUserFormMixin(object):
|
||||||
self.fields['home'].widget = forms.Select(choices=choices)
|
self.fields['home'].widget = forms.Select(choices=choices)
|
||||||
if self.instance.pk and (self.instance.is_main or self.instance.has_shell):
|
if self.instance.pk and (self.instance.is_main or self.instance.has_shell):
|
||||||
# hidde home option for shell users
|
# hidde home option for shell users
|
||||||
self.fields['home'].widget = forms.HiddenInput()
|
self.fields['home'].widget.input_type = 'hidden'
|
||||||
self.fields['directory'].widget = forms.HiddenInput()
|
self.fields['directory'].widget.input_type = 'hidden'
|
||||||
elif self.instance.pk and (self.instance.get_base_home() == self.instance.home):
|
elif self.instance.pk and (self.instance.get_base_home() == self.instance.home):
|
||||||
self.fields['directory'].widget = forms.HiddenInput()
|
self.fields['directory'].widget = forms.HiddenInput()
|
||||||
else:
|
else:
|
||||||
self.fields['directory'].widget = forms.TextInput(attrs={'size':'70'})
|
self.fields['directory'].widget = forms.TextInput(attrs={'size':'70'})
|
||||||
if not self.instance.pk or not self.instance.is_main:
|
if not self.instance.pk or not self.instance.is_main:
|
||||||
# Some javascript for hidde home/directory inputs when convinient
|
# Some javascript for hidde home/directory inputs when convinient
|
||||||
self.fields['shell'].widget.attrs = {
|
self.fields['shell'].widget.attrs['onChange'] = textwrap.dedent("""\
|
||||||
'onChange': textwrap.dedent("""\
|
field = $(".field-home, .field-directory");
|
||||||
field = $(".field-home, .field-directory");
|
input = $("#id_home, #id_directory");
|
||||||
input = $("#id_home, #id_directory");
|
if ($.inArray(this.value, %s) < 0) {
|
||||||
if ($.inArray(this.value, %s) < 0) {
|
field.addClass("hidden");
|
||||||
field.addClass("hidden");
|
|
||||||
} else {
|
|
||||||
field.removeClass("hidden");
|
|
||||||
input.removeAttr("type");
|
|
||||||
};""" % str(list(settings.SYSTEMUSERS_DISABLED_SHELLS)))
|
|
||||||
}
|
|
||||||
self.fields['home'].widget.attrs = {
|
|
||||||
'onChange': textwrap.dedent("""\
|
|
||||||
field = $(".field-box.field-directory");
|
|
||||||
input = $("#id_directory");
|
|
||||||
if (this.value.search("%s") > 0) {
|
|
||||||
field.addClass("hidden");
|
|
||||||
} else {
|
} else {
|
||||||
field.removeClass("hidden");
|
field.removeClass("hidden");
|
||||||
input.removeAttr("type");
|
input.removeAttr("type");
|
||||||
};""" % username)
|
};""" % str(list(settings.SYSTEMUSERS_DISABLED_SHELLS))
|
||||||
}
|
)
|
||||||
|
self.fields['home'].widget.attrs['onChange'] = textwrap.dedent("""\
|
||||||
|
field = $(".field-box.field-directory");
|
||||||
|
input = $("#id_directory");
|
||||||
|
if (this.value.search("%s") > 0) {
|
||||||
|
field.addClass("hidden");
|
||||||
|
} else {
|
||||||
|
field.removeClass("hidden");
|
||||||
|
input.removeAttr("type");
|
||||||
|
};""" % username
|
||||||
|
)
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
super(SystemUserFormMixin, self).clean()
|
super(SystemUserFormMixin, self).clean()
|
||||||
cleaned_data = self.cleaned_data
|
cleaned_data = self.cleaned_data
|
||||||
home = cleaned_data.get('home')
|
home = cleaned_data.get('home')
|
||||||
|
shell = cleaned_data.get('shell')
|
||||||
if home and self.MOCK_USERNAME in home:
|
if home and self.MOCK_USERNAME in home:
|
||||||
username = cleaned_data.get('username', '')
|
username = cleaned_data.get('username', '')
|
||||||
cleaned_data['home'] = home.replace(self.MOCK_USERNAME, username)
|
cleaned_data['home'] = home.replace(self.MOCK_USERNAME, username)
|
||||||
|
elif home and shell not in settings.SYSTEMUSERS_DISABLED_SHELLS:
|
||||||
|
cleaned_data['home'] = ''
|
||||||
|
cleaned_data['directory'] = ''
|
||||||
validate_home(self.instance, cleaned_data, self.account)
|
validate_home(self.instance, cleaned_data, self.account)
|
||||||
return cleaned_data
|
return cleaned_data
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from orchestra.contrib.orchestration import Operation
|
from orchestra.contrib.orchestration import Operation
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ from django.contrib.auth import BACKEND_SESSION_KEY, SESSION_KEY
|
||||||
from django.contrib.sessions.backends.db import SessionStore
|
from django.contrib.sessions.backends.db import SessionStore
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.test import LiveServerTestCase, TestCase
|
from django.test import LiveServerTestCase, TestCase
|
||||||
from orm.api import Api
|
|
||||||
from selenium.webdriver.firefox.webdriver import WebDriver
|
from selenium.webdriver.firefox.webdriver import WebDriver
|
||||||
from xvfbwrapper import Xvfb
|
from xvfbwrapper import Xvfb
|
||||||
|
|
||||||
|
@ -88,6 +87,7 @@ class BaseLiveServerTestCase(AppDependencyMixin, LiveServerTestCase):
|
||||||
return Account.objects.create_user(username, password=password, email='orchestra@orchestra.org')
|
return Account.objects.create_user(username, password=password, email='orchestra@orchestra.org')
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
from orm.api import Api
|
||||||
super(BaseLiveServerTestCase, self).setUp()
|
super(BaseLiveServerTestCase, self).setUp()
|
||||||
self.rest = Api(self.live_server_url + '/api/')
|
self.rest = Api(self.live_server_url + '/api/')
|
||||||
self.rest.enable_logging()
|
self.rest.enable_logging()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
django==1.8.1
|
django==1.8.1
|
||||||
django-celery-email==1.0.4
|
django-celery-email==1.0.4
|
||||||
django-fluent-dashboard==0.5
|
django-fluent-dashboard==0.5
|
||||||
https://bitbucket.org/izi/django-admin-tools/get/a0abfffd76a0.zip
|
https://github.com/glic3rinu/django-admin-tools/archive/master.zip
|
||||||
IPy==0.81
|
IPy==0.81
|
||||||
django-extensions==1.5.2
|
django-extensions==1.5.2
|
||||||
django-transaction-signals==1.0.0
|
django-transaction-signals==1.0.0
|
||||||
|
|
|
@ -94,7 +94,6 @@ chown $USER:$USER /home/orchestra/panel/orchestra.log
|
||||||
|
|
||||||
# admin_tools needs accounts and does not have migrations
|
# admin_tools needs accounts and does not have migrations
|
||||||
if [[ ! $(sudo su postgres -c "psql orchestra -q -c 'SELECT * FROM accounts_account LIMIT 1;' 2> /dev/null") ]]; then
|
if [[ ! $(sudo su postgres -c "psql orchestra -q -c 'SELECT * FROM accounts_account LIMIT 1;' 2> /dev/null") ]]; then
|
||||||
surun "$PYTHON_BIN $MANAGE migrate --noinput accounts"
|
|
||||||
surun "$PYTHON_BIN $MANAGE migrate --noinput"
|
surun "$PYTHON_BIN $MANAGE migrate --noinput"
|
||||||
else
|
else
|
||||||
surun "$PYTHON_BIN $MANAGE postupgradeorchestra --from $CURRENT_VERSION"
|
surun "$PYTHON_BIN $MANAGE postupgradeorchestra --from $CURRENT_VERSION"
|
||||||
|
|
Loading…
Reference in New Issue