Improved SaaS wordpress form

This commit is contained in:
Marc Aymerich 2015-09-21 10:28:49 +00:00
parent 75b08f7216
commit 760d6956de
10 changed files with 113 additions and 93 deletions

14
TODO.md
View file

@ -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

View file

@ -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)
) )

View 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 = '&lt;site_name&gt;.%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

View file

@ -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'}))

View file

@ -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."))

View file

@ -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"))

View file

@ -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 = '&lt;site_name&gt;.%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

View file

@ -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'))

View file

@ -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."))

View file

@ -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"))