Improved SaaS wordpress form
This commit is contained in:
parent
75b08f7216
commit
760d6956de
14
TODO.md
14
TODO.md
|
@ -210,18 +210,10 @@ https://code.djangoproject.com/ticket/24576
|
||||||
* move all tests to django-orchestra/tests
|
* move all tests to django-orchestra/tests
|
||||||
* *natural keys: those fields that uniquely identify a service, list.name, website.name, webapp.name+account, make sure rest api can not edit thos things
|
* *natural keys: those fields that uniquely identify a service, list.name, website.name, webapp.name+account, make sure rest api can not edit thos things
|
||||||
|
|
||||||
|
|
||||||
* MultiCHoiceField proper serialization
|
* MultiCHoiceField proper serialization
|
||||||
|
|
||||||
* UNIFY PHP FPM settings name
|
|
||||||
# virtualhost name: name-account?
|
|
||||||
* add a delay to changes on the webserver apache to no overwelm it with backend executions?
|
|
||||||
* replace unique_name by natural_key?
|
* replace unique_name by natural_key?
|
||||||
* do not require contact or create default
|
* do not require contact or create default
|
||||||
* send signals for backend triggers
|
|
||||||
* force ignore slack billing period overridig when billing
|
|
||||||
* fpm reload starts new pools?
|
|
||||||
* rename resource.monitors to resource.backends ?
|
|
||||||
* abstract model classes that enabling overriding, and ORCHESTRA_DATABASE_MODEL settings + orchestra.get_database_model() instead of explicitly importing from orchestra.contrib.databases.models import Database.. (Admin and REST API are fucked then?)
|
* abstract model classes that enabling overriding, and ORCHESTRA_DATABASE_MODEL settings + orchestra.get_database_model() instead of explicitly importing from orchestra.contrib.databases.models import Database.. (Admin and REST API are fucked then?)
|
||||||
|
|
||||||
# billing order list filter detect metrics that are greater from those of billing_date
|
# billing order list filter detect metrics that are greater from those of billing_date
|
||||||
|
@ -380,8 +372,6 @@ Case
|
||||||
|
|
||||||
# round decimals on every billing operation
|
# round decimals on every billing operation
|
||||||
|
|
||||||
# PHPlist cron, bounces and traffic (maybe specific mail script with sitename)
|
|
||||||
|
|
||||||
# use "su $user --shell /bin/bash" on backends for security : MKDIR -p...
|
# use "su $user --shell /bin/bash" on backends for security : MKDIR -p...
|
||||||
|
|
||||||
# model.field.flatchoices
|
# model.field.flatchoices
|
||||||
|
@ -396,3 +386,7 @@ Case
|
||||||
|
|
||||||
|
|
||||||
# Implement wordpressmu change password or remove password from the form
|
# Implement wordpressmu change password or remove password from the form
|
||||||
|
|
||||||
|
# Deprecate orchestra start/stop/restart services management commands?
|
||||||
|
|
||||||
|
# Enable/disable ignore period orders list filter
|
||||||
|
|
|
@ -89,7 +89,7 @@ class ApacheTrafficByHost(ServiceMonitor):
|
||||||
sys.stderr.write(str(e)+'\\n')
|
sys.stderr.write(str(e)+'\\n')
|
||||||
for opts in sites.values():
|
for opts in sites.values():
|
||||||
ini_date, object_id, size = opts
|
ini_date, object_id, size = opts
|
||||||
print object_id, size
|
sys.stdout.write('%s %s\n' % (object_id, size))
|
||||||
""").format(**context)
|
""").format(**context)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
76
orchestra/contrib/saas/forms.py
Normal file
76
orchestra/contrib/saas/forms.py
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
from django import forms
|
||||||
|
from django.core.validators import RegexValidator
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from orchestra.core import validators
|
||||||
|
from orchestra.forms.widgets import SpanWidget
|
||||||
|
from orchestra.plugins.forms import PluginDataForm
|
||||||
|
from orchestra.utils.python import random_ascii
|
||||||
|
|
||||||
|
|
||||||
|
class SaaSBaseForm(PluginDataForm):
|
||||||
|
site_url = forms.CharField(label=_("Site URL"), widget=SpanWidget(), required=False)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
exclude = ('database',)
|
||||||
|
readonly_fields = ('site_url',)
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(SaaSBaseForm, self).__init__(*args, **kwargs)
|
||||||
|
self.is_change = bool(self.instance and self.instance.pk)
|
||||||
|
if self.is_change:
|
||||||
|
site_domain = self.instance.get_site_domain()
|
||||||
|
else:
|
||||||
|
site_domain = self.plugin.site_domain
|
||||||
|
if site_domain:
|
||||||
|
site_link = '<a href="http://%s">%s</a>' % (site_domain, site_domain)
|
||||||
|
else:
|
||||||
|
site_link = '<site_name>.%s' % self.plugin.site_base_domain
|
||||||
|
self.fields['site_url'].widget.display = site_link
|
||||||
|
self.fields['name'].label = _("Site name") if self.plugin.site_base_domain else _("Username")
|
||||||
|
|
||||||
|
|
||||||
|
class SaaSPasswordForm(SaaSBaseForm):
|
||||||
|
password = forms.CharField(label=_("Password"), required=False,
|
||||||
|
widget=SpanWidget(display='<strong>Unknown password</strong>'),
|
||||||
|
validators=[
|
||||||
|
validators.validate_password,
|
||||||
|
RegexValidator(r'^[^"\'\\]+$',
|
||||||
|
_('Enter a valid password. '
|
||||||
|
'This value may contain any ascii character except for '
|
||||||
|
' \'/"/\\/ characters.'), 'invalid'),
|
||||||
|
],
|
||||||
|
help_text=_("Passwords are not stored, so there is no way to see this "
|
||||||
|
"service's password, but you can change the password using "
|
||||||
|
"<a href=\"password/\">this form</a>."))
|
||||||
|
password1 = forms.CharField(label=_("Password"), validators=[validators.validate_password],
|
||||||
|
widget=forms.PasswordInput)
|
||||||
|
password2 = forms.CharField(label=_("Password confirmation"),
|
||||||
|
widget=forms.PasswordInput,
|
||||||
|
help_text=_("Enter the same password as above, for verification."))
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(SaaSPasswordForm, self).__init__(*args, **kwargs)
|
||||||
|
if self.is_change:
|
||||||
|
self.fields['password1'].required = False
|
||||||
|
self.fields['password1'].widget = forms.HiddenInput()
|
||||||
|
self.fields['password2'].required = False
|
||||||
|
self.fields['password2'].widget = forms.HiddenInput()
|
||||||
|
else:
|
||||||
|
self.fields['password'].widget = forms.HiddenInput()
|
||||||
|
self.fields['password1'].help_text = _("Suggestion: %s") % random_ascii(10)
|
||||||
|
|
||||||
|
def clean_password2(self):
|
||||||
|
if not self.is_change:
|
||||||
|
password1 = self.cleaned_data.get("password1")
|
||||||
|
password2 = self.cleaned_data.get("password2")
|
||||||
|
if password1 and password2 and password1 != password2:
|
||||||
|
msg = _("The two password fields didn't match.")
|
||||||
|
raise forms.ValidationError(msg)
|
||||||
|
return password2
|
||||||
|
|
||||||
|
def save(self, commit=True):
|
||||||
|
obj = super(SoftwareServiceForm, self).save(commit=commit)
|
||||||
|
if not self.is_change:
|
||||||
|
obj.set_password(self.cleaned_data["password1"])
|
||||||
|
return obj
|
|
@ -3,10 +3,11 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from .. import settings
|
from .. import settings
|
||||||
from .options import SoftwareService, SoftwareServiceForm
|
from ..forms import SaaSPasswordForm
|
||||||
|
from .options import SoftwareService
|
||||||
|
|
||||||
|
|
||||||
class BSCWForm(SoftwareServiceForm):
|
class BSCWForm(SaaSPasswordForm):
|
||||||
email = forms.EmailField(label=_("Email"), widget=forms.TextInput(attrs={'size':'40'}))
|
email = forms.EmailField(label=_("Email"), widget=forms.TextInput(attrs={'size':'40'}))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,12 +4,12 @@ from rest_framework import serializers
|
||||||
|
|
||||||
from orchestra.forms import widgets
|
from orchestra.forms import widgets
|
||||||
|
|
||||||
from .options import SoftwareService, SoftwareServiceForm
|
|
||||||
|
|
||||||
from .. import settings
|
from .. import settings
|
||||||
|
from ..forms import SaaSPasswordForm
|
||||||
|
from .options import SoftwareService
|
||||||
|
|
||||||
|
|
||||||
class GitLabForm(SoftwareServiceForm):
|
class GitLabForm(SaaSPasswordForm):
|
||||||
email = forms.EmailField(label=_("Email"),
|
email = forms.EmailField(label=_("Email"),
|
||||||
help_text=_("Initial email address, changes on the GitLab server are not reflected here."))
|
help_text=_("Initial email address, changes on the GitLab server are not reflected here."))
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from .options import SoftwareService, SoftwareServiceForm
|
from ..forms import SaaSPasswordForm
|
||||||
|
from .options import SoftwareService
|
||||||
|
|
||||||
|
|
||||||
class MoodleForm(SoftwareServiceForm):
|
class MoodleForm(SaaSPasswordForm):
|
||||||
email = forms.EmailField(label=_("Email"))
|
email = forms.EmailField(label=_("Email"))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,81 +1,17 @@
|
||||||
from django import forms
|
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.core.validators import RegexValidator
|
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from orchestra import plugins
|
from orchestra import plugins
|
||||||
from orchestra.contrib.orchestration import Operation
|
from orchestra.contrib.orchestration import Operation
|
||||||
from orchestra.core import validators
|
|
||||||
from orchestra.forms.widgets import SpanWidget
|
|
||||||
from orchestra.plugins.forms import PluginDataForm
|
|
||||||
from orchestra.utils.functional import cached
|
from orchestra.utils.functional import cached
|
||||||
from orchestra.utils.python import import_class, random_ascii
|
from orchestra.utils.python import import_class
|
||||||
|
|
||||||
from .. import settings
|
from .. import settings
|
||||||
|
from ..forms import SaaSPasswordForm
|
||||||
|
|
||||||
class SoftwareServiceForm(PluginDataForm):
|
|
||||||
site_url = forms.CharField(label=_("Site URL"), widget=SpanWidget(), required=False)
|
|
||||||
password = forms.CharField(label=_("Password"), required=False,
|
|
||||||
widget=SpanWidget(display='<strong>Unknown password</strong>'),
|
|
||||||
validators=[
|
|
||||||
validators.validate_password,
|
|
||||||
RegexValidator(r'^[^"\'\\]+$',
|
|
||||||
_('Enter a valid password. '
|
|
||||||
'This value may contain any ascii character except for '
|
|
||||||
' \'/"/\\/ characters.'), 'invalid'),
|
|
||||||
],
|
|
||||||
help_text=_("Passwords are not stored, so there is no way to see this "
|
|
||||||
"service's password, but you can change the password using "
|
|
||||||
"<a href=\"password/\">this form</a>."))
|
|
||||||
password1 = forms.CharField(label=_("Password"), validators=[validators.validate_password],
|
|
||||||
widget=forms.PasswordInput)
|
|
||||||
password2 = forms.CharField(label=_("Password confirmation"),
|
|
||||||
widget=forms.PasswordInput,
|
|
||||||
help_text=_("Enter the same password as above, for verification."))
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
exclude = ('database',)
|
|
||||||
readonly_fields = ('site_url',)
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super(SoftwareServiceForm, self).__init__(*args, **kwargs)
|
|
||||||
self.is_change = bool(self.instance and self.instance.pk)
|
|
||||||
if self.is_change:
|
|
||||||
site_domain = self.instance.get_site_domain()
|
|
||||||
self.fields['password1'].required = False
|
|
||||||
self.fields['password1'].widget = forms.HiddenInput()
|
|
||||||
self.fields['password2'].required = False
|
|
||||||
self.fields['password2'].widget = forms.HiddenInput()
|
|
||||||
else:
|
|
||||||
self.fields['password'].widget = forms.HiddenInput()
|
|
||||||
self.fields['password1'].help_text = _("Suggestion: %s") % random_ascii(10)
|
|
||||||
site_domain = self.plugin.site_domain
|
|
||||||
if site_domain:
|
|
||||||
site_link = '<a href="http://%s">%s</a>' % (site_domain, site_domain)
|
|
||||||
else:
|
|
||||||
site_link = '<site_name>.%s' % self.plugin.site_base_domain
|
|
||||||
self.fields['site_url'].widget.display = site_link
|
|
||||||
self.fields['name'].label = _("Site name") if self.plugin.site_base_domain else _("Username")
|
|
||||||
|
|
||||||
def clean_password2(self):
|
|
||||||
if not self.is_change:
|
|
||||||
password1 = self.cleaned_data.get("password1")
|
|
||||||
password2 = self.cleaned_data.get("password2")
|
|
||||||
if password1 and password2 and password1 != password2:
|
|
||||||
msg = _("The two password fields didn't match.")
|
|
||||||
raise forms.ValidationError(msg)
|
|
||||||
return password2
|
|
||||||
|
|
||||||
def save(self, commit=True):
|
|
||||||
obj = super(SoftwareServiceForm, self).save(commit=commit)
|
|
||||||
if not self.is_change:
|
|
||||||
obj.set_password(self.cleaned_data["password1"])
|
|
||||||
return obj
|
|
||||||
|
|
||||||
|
|
||||||
class SoftwareService(plugins.Plugin):
|
class SoftwareService(plugins.Plugin):
|
||||||
form = SoftwareServiceForm
|
form = SaaSPasswordForm
|
||||||
site_domain = None
|
site_domain = None
|
||||||
site_base_domain = None
|
site_base_domain = None
|
||||||
has_custom_domain = False
|
has_custom_domain = False
|
||||||
|
|
|
@ -8,10 +8,11 @@ from orchestra.contrib.databases.models import Database, DatabaseUser
|
||||||
from orchestra.forms.widgets import SpanWidget
|
from orchestra.forms.widgets import SpanWidget
|
||||||
|
|
||||||
from .. import settings
|
from .. import settings
|
||||||
from .options import SoftwareService, SoftwareServiceForm
|
from ..forms import SaaSPasswordForm
|
||||||
|
from .options import SoftwareService
|
||||||
|
|
||||||
|
|
||||||
class PHPListForm(SoftwareServiceForm):
|
class PHPListForm(SaaSPasswordForm):
|
||||||
admin_username = forms.CharField(label=_("Admin username"), required=False,
|
admin_username = forms.CharField(label=_("Admin username"), required=False,
|
||||||
widget=SpanWidget(display='admin'))
|
widget=SpanWidget(display='admin'))
|
||||||
|
|
||||||
|
|
|
@ -3,12 +3,13 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from .. import settings
|
from .. import settings
|
||||||
from .options import SoftwareService, SoftwareServiceForm
|
from ..forms import SaaSPasswordForm
|
||||||
|
from .options import SoftwareService
|
||||||
|
|
||||||
|
|
||||||
# TODO monitor quota since out of sync?
|
# TODO monitor quota since out of sync?
|
||||||
|
|
||||||
class SeaFileForm(SoftwareServiceForm):
|
class SeaFileForm(SaaSPasswordForm):
|
||||||
email = forms.EmailField(label=_("Email"), widget=forms.TextInput(attrs={'size':'40'}))
|
email = forms.EmailField(label=_("Email"), widget=forms.TextInput(attrs={'size':'40'}))
|
||||||
quota = forms.IntegerField(label=_("Quota"), initial=settings.SAAS_SEAFILE_DEFAULT_QUOTA,
|
quota = forms.IntegerField(label=_("Quota"), initial=settings.SAAS_SEAFILE_DEFAULT_QUOTA,
|
||||||
help_text=_("Disk quota in MB."))
|
help_text=_("Disk quota in MB."))
|
||||||
|
|
|
@ -1,13 +1,23 @@
|
||||||
from django import forms
|
from django import forms
|
||||||
|
from django.utils.safestring import mark_safe
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from .options import SoftwareService, SoftwareServiceForm
|
from .options import SoftwareService
|
||||||
|
from ..forms import SaaSBaseForm
|
||||||
|
|
||||||
|
|
||||||
class WordPressForm(SoftwareServiceForm):
|
class WordPressForm(SaaSBaseForm):
|
||||||
email = forms.EmailField(label=_("Email"), widget=forms.TextInput(attrs={'size':'40'}))
|
email = forms.EmailField(label=_("Email"), widget=forms.TextInput(attrs={'size':'40'}),
|
||||||
|
help_text=_("A new user will be created if the above email address is not in the database.<br>"
|
||||||
|
"The username and password will be mailed to this email address."))
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(WordPressForm, self).__init__(*args, **kwargs)
|
||||||
|
if self.is_change:
|
||||||
|
admin_url = 'http://%s/wp-admin/' % self.instance.get_site_domain()
|
||||||
|
help_text = 'Admin URL: <a href="{0}">{0}</a>'.format(admin_url)
|
||||||
|
self.fields['site_url'].help_text = mark_safe(help_text)
|
||||||
|
|
||||||
class WordPressDataSerializer(serializers.Serializer):
|
class WordPressDataSerializer(serializers.Serializer):
|
||||||
email = serializers.EmailField(label=_("Email"))
|
email = serializers.EmailField(label=_("Email"))
|
||||||
|
|
Loading…
Reference in a new issue