Implemented enable admin action0

This commit is contained in:
Marc Aymerich 2016-03-31 16:02:50 +00:00
parent 6a34ba8fd2
commit 4adfd4c83a
26 changed files with 183 additions and 98 deletions

View File

@ -437,3 +437,11 @@ mkhomedir_helper or create ssh homes with bash.rc and such
# Warning websites with ssl options without https protocol
# Schedule cancellation
# Multiple domains wordpress
# TODO: separate ports for fpm version
# Reversion
# implement re-enable account
# Disable/enable saas and VPS

View File

@ -1,3 +1,5 @@
from functools import partial
from django.contrib import admin
from django.core.mail import send_mass_mail
from django.shortcuts import render
@ -108,23 +110,36 @@ class SendEmail(object):
return render(request, self.template, self.context)
@action_with_confirmation()
def disable(modeladmin, request, queryset):
def base_disable(modeladmin, request, queryset, disable=True):
num = 0
action_name = _("disabled") if disable else _("enabled")
for obj in queryset:
obj.disable()
modeladmin.log_change(request, obj, _("Disabled"))
obj.disable() if disable else obj.enable()
modeladmin.log_change(request, obj, action_name.capitalize())
num += 1
opts = modeladmin.model._meta
context = {
'action_name': action_name,
'verbose_name': opts.verbose_name,
'verbose_name_plural': opts.verbose_name_plural,
'num': num
}
msg = ungettext(
_("Selected %(verbose_name)s and related services has been disabled.") % context,
_("%(num)s selected %(verbose_name_plural)s and related services have been disabled.") % context,
_("Selected %(verbose_name)s and related services has been %(action_name)s.") % context,
_("%(num)s selected %(verbose_name_plural)s and related services have been %(action_name)s.") % context,
num)
modeladmin.message_user(request, msg)
@action_with_confirmation()
def disable(modeladmin, request, queryset):
return base_disable(modeladmin, request, queryset)
disable.url_name = 'disable'
disable.short_description = _("Disable")
@action_with_confirmation()
def enable(modeladmin, request, queryset):
return base_disable(modeladmin, request, queryset, disable=False)
enable.url_name = 'enable'
enable.short_description = _("Enable")

View File

@ -149,7 +149,7 @@ class ChangeViewActionsMixin(object):
kwargs['extra_context']['object_tools_items'] = [
action.__dict__ for action in self.get_change_view_actions(obj)
]
return super(ChangeViewActionsMixin, self).change_view(request, object_id, **kwargs)
return super().change_view(request, object_id, **kwargs)
class ChangeAddFieldsMixin(object):

View File

@ -1,3 +1,5 @@
from functools import partial, wraps
from django.contrib import messages
from django.contrib.admin import helpers
from django.contrib.admin.utils import NestedObjects, quote
@ -186,21 +188,21 @@ def delete_related_services(modeladmin, request, queryset):
delete_related_services.short_description = _("Delete related services")
def disable_selected(modeladmin, request, queryset):
def disable_selected(modeladmin, request, queryset, disable=True):
opts = modeladmin.model._meta
app_label = opts.app_label
verbose_action_name = _("disabled") if disable else _("enabled")
# The user has already confirmed the deletion.
# Do the disable and return a None to display the change list view again.
if request.POST.get('post'):
n = 0
for account in queryset:
account.disable()
modeladmin.log_change(request, account, _("Disabled"))
account.disable() if disable else account.enable()
modeladmin.log_change(request, account, verbose_action_name.capitalize())
n += 1
modeladmin.message_user(request, ungettext(
_("One account has been successfully disabled."),
_("%i accounts have been successfully disabled.") % n,
_("One account has been successfully %s.") % verbose_action_name,
_("%i accounts have been successfully %s.") % (n, verbose_action_name),
n)
)
return None
@ -248,6 +250,8 @@ def disable_selected(modeladmin, request, queryset):
context = dict(
admin_site.each_context(request),
action_name='disable_selected' if disable else 'enable_selected',
disable=disable,
title=_("Are you sure?"),
objects_name=objects_name,
deletable_objects=display,
@ -259,5 +263,11 @@ def disable_selected(modeladmin, request, queryset):
template = 'admin/%s/%s/disable_selected_confirmation.html' % (app_label, opts.model_name)
return TemplateResponse(request, template, context)
disable_selected.short_description = _("Disable selected accounts")
disable_selected.url = 'disable'
disable_selected.url_name = 'disable'
disable_selected.tool_description = _("Disable")
enable_selected = partial(disable_selected, disable=False)
enable_selected.__name__ = 'enable_selected'
enable_selected.url_name = 'enable'
enable_selected.tool_description = _("Enable")

View File

@ -20,7 +20,8 @@ from orchestra.admin.utils import wrap_admin_view, admin_link, set_url_query
from orchestra.core import services, accounts
from orchestra.forms import UserChangeForm
from .actions import list_contacts, service_report, delete_related_services, disable_selected
from .actions import (list_contacts, service_report, delete_related_services, disable_selected,
enable_selected)
from .filters import HasMainUserListFilter
from .forms import AccountCreationForm
from .models import Account
@ -64,9 +65,10 @@ class AccountAdmin(ChangePasswordAdminMixin, auth.UserAdmin, ExtendedModelAdmin)
change_readonly_fields = ('username', 'main_systemuser_link', 'is_active')
change_form_template = 'admin/accounts/account/change_form.html'
actions = (
disable_selected, delete_related_services, list_contacts, service_report, SendEmail()
disable_selected, enable_selected, delete_related_services, list_contacts, service_report,
SendEmail()
)
change_view_actions = (disable_selected, service_report)
change_view_actions = (disable_selected, service_report, enable_selected)
ordering = ()
main_systemuser_link = admin_link('main_systemuser')
@ -111,6 +113,14 @@ class AccountAdmin(ChangePasswordAdminMixin, auth.UserAdmin, ExtendedModelAdmin)
else:
super(AccountAdmin, self).save_model(request, obj, form, change)
def get_change_view_actions(self, obj=None):
views = super().get_change_view_actions(obj=obj)
if obj is not None:
if obj.is_active:
return [view for view in views if view.url_name != 'enable']
return [view for view in views if view.url_name != 'disable']
return views
def get_actions(self, request):
actions = super(AccountAdmin, self).get_actions(request)
if 'delete_selected' in actions:

View File

@ -83,6 +83,11 @@ class Account(auth.AbstractBaseUser):
self.save(update_fields=('is_active',))
self.notify_related()
def enable(self):
self.is_active = True
self.save(update_fields=('is_active',))
self.notify_related()
def get_services_to_disable(self):
for rel in self._meta.get_all_related_objects():
source = getattr(rel, 'related_model', rel.model)

View File

@ -8,42 +8,28 @@
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
&rsaquo; <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
&rsaquo; <a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>
&rsaquo; {% trans 'Disable accounts' %}
&rsaquo; {% if disable%}{% blocktrans %}Disable {{ objects_name }}{% endblocktrans %}{% else %}{% blocktrans %}Enable {{ objects_name }}{% endblocktrans %}{% endif %}
</div>
{% endblock %}
{% block content %}
{% if perms_lacking %}
<p>{% blocktrans %}Disabling the selected {{ objects_name }} would result in disabling related objects, but your account doesn't have permission to disable the following types of objects:{% endblocktrans %}</p>
<ul>
{% for obj in perms_lacking %}
<li>{{ obj }}</li>
{% endfor %}
</ul>
{% elif protected %}
<p>{% blocktrans %}Deleting the selected {{ objects_name }} would require deleting the following protected related objects:{% endblocktrans %}</p>
<ul>
{% for obj in protected %}
<li>{{ obj }}</li>
{% endfor %}
</ul>
{% else %}
<p>{% blocktrans %}Are you sure you want to disable the selected {{ objects_name }}? All of the following objects and their related items will be disabled:{% endblocktrans %}</p>
<h2>{% trans "Objects" %}</h2>
{% for deletable_object in deletable_objects %}
<ul>{{ deletable_object|unordered_list }}</ul>
{% endfor %}
<form action="" method="post">{% csrf_token %}
<div>
{% for obj in queryset %}
<input type="hidden" name="{{ action_checkbox_name }}" value="{{ obj.pk|unlocalize }}" />
{% endfor %}
<input type="hidden" name="action" value="disable_selected" />
<input type="hidden" name="post" value="yes" />
<input type="submit" value="{% trans "Yes, I'm sure" %}" />
<a href="#" onclick="window.history.back(); return false;" class="button cancel-link">{% trans "No, take me back" %}</a>
</div>
</form>
{% if disable%}<p>{% blocktrans %}Are you sure you want to disable selected {{ objects_name }}?{% endblocktrans %}</p>
{% else %}<p>{% blocktrans %}Are you sure you want to enable selected {{ objects_name }}?{% endblocktrans %}</p>
{% endif %}
<h2>{% trans "Objects" %}</h2>
{% for deletable_object in deletable_objects %}
<ul>{{ deletable_object|unordered_list }}</ul>
{% endfor %}
<form action="" method="post">{% csrf_token %}
<div>
{% for obj in queryset %}
<input type="hidden" name="{{ action_checkbox_name }}" value="{{ obj.pk|unlocalize }}" />
{% endfor %}
<input type="hidden" name="action" value="{{ action_name }}" />
<input type="hidden" name="post" value="yes" />
<input type="submit" value="{% trans "Yes, I'm sure" %}" />
<a href="#" onclick="window.history.back(); return false;" class="button cancel-link">{% trans "No, take me back" %}</a>
</div>
</form>
{% endblock %}

View File

@ -292,7 +292,7 @@ class BillAdmin(AccountAdminMixin, ExtendedModelAdmin):
state = bill.get_payment_state_display().upper()
title = ''
if bill.closed_amends:
state += '*'
state = '<strike>%s*</strike>' % state
title = _("This bill has been amended, this value may not be valid.")
color = PAYMENT_STATE_COLORS.get(bill.payment_state, 'grey')
return '<a href="{url}" style="color:{color}" title="{title}">{name}</a>'.format(

View File

@ -78,7 +78,10 @@ class Domain(models.Model):
@property
def is_top(self):
# don't cache, don't replace by top_id
return not bool(self.top)
try:
return not bool(self.top)
except Domain.DoesNotExist:
return False
@property
def subdomains(self):

View File

@ -11,7 +11,7 @@ from .helpers import markdown_formated_changes
from .models import Queue, Ticket
def change_ticket_state_factory(action, final_state):
def change_ticket_state_factory(action, verbose_name, final_state):
context = {
'action': action,
'form': ChangeReasonForm()
@ -40,30 +40,31 @@ def change_ticket_state_factory(action, final_state):
'count': queryset.count(),
'state': final_state.lower()
}
msg = _("%s selected tickets are now %s.") % context
msg = _("%(count)s selected tickets are now %(state)s.") % context
modeladmin.message_user(request, msg)
else:
context['form'] = form
# action_with_confirmation must display form validation errors
return True
change_ticket_state.url_name = action
change_ticket_state.verbose_name = action
change_ticket_state.short_description = _('%s selected tickets') % action.capitalize()
change_ticket_state.tool_description = verbose_name
change_ticket_state.short_description = _('%s selected tickets') % verbose_name
change_ticket_state.help_text = _('Mark ticket as %s.') % final_state.lower()
change_ticket_state.__name__ = action
return change_ticket_state
action_map = {
Ticket.RESOLVED: 'resolve',
Ticket.REJECTED: 'reject',
Ticket.CLOSED: 'close'
Ticket.RESOLVED: ('resolve', _("Resolve")),
Ticket.REJECTED: ('reject', _("Reject")),
Ticket.CLOSED: ('close', _("Close")),
}
thismodule = sys.modules[__name__]
for state, name in action_map.items():
action = change_ticket_state_factory(name, state)
for state, names in action_map.items():
name, verbose_name = names
action = change_ticket_state_factory(name, verbose_name, state)
setattr(thismodule, '%s_tickets' % name, action)
@ -89,6 +90,7 @@ def take_tickets(modeladmin, request, queryset):
msg = _("%(count)s selected tickets are now owned by %(user)s.") % context
modeladmin.message_user(request, msg)
take_tickets.url_name = 'take'
take_tickets.tool_description = _("Take")
take_tickets.short_description = _("Take selected tickets")
take_tickets.help_text = _("Make yourself owner of the ticket.")

View File

@ -65,7 +65,6 @@ class MessageReadOnlyInline(admin.TabularInline):
content_html.short_description = _("Content")
content_html.allow_tags = True
def has_add_permission(self, request):
return False
@ -125,11 +124,10 @@ class TicketAdmin(ExtendedModelAdmin):
)
list_display_links = ('unbold_id', 'bold_subject')
list_filter = (
MyTicketsListFilter, 'queue__name', 'priority', TicketStateListFilter,
MyTicketsListFilter, 'queue', 'priority', TicketStateListFilter,
)
default_changelist_filters = (
('my_tickets', lambda r: 'True' if not r.user.is_superuser else 'False'),
('state', 'OPEN')
('state', 'OPEN'),
)
date_hierarchy = 'created_at'
search_fields = (
@ -298,7 +296,7 @@ class QueueAdmin(admin.ModelAdmin):
def num_tickets(self, queue):
num = queue.tickets__count
url = reverse('admin:issues_ticket_changelist')
url += '?my_tickets=False&queue=%i' % queue.pk
url += '?queue=%i' % queue.pk
return '<a href="%s">%d</a>' % (url, num)
num_tickets.short_description = _("Tickets")
num_tickets.admin_order_field = 'tickets__count'

View File

@ -12,19 +12,12 @@ class MyTicketsListFilter(SimpleListFilter):
def lookups(self, request, model_admin):
return (
('True', _("My Tickets")),
('False', _("All")),
)
def queryset(self, request, queryset):
if self.value() == 'True':
return queryset.involved_by(request.user)
def choices(self, cl):
""" Remove default All """
choices = iter(super(MyTicketsListFilter, self).choices(cl))
next(choices)
return choices
class TicketStateListFilter(SimpleListFilter):
title = 'State'

View File

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
import datetime
from django.utils.timezone import utc
class Migration(migrations.Migration):
dependencies = [
('issues', '0002_auto_20150709_1018'),
]
operations = [
migrations.RemoveField(
model_name='message',
name='created_on',
),
migrations.AddField(
model_name='message',
name='created_at',
field=models.DateTimeField(auto_now_add=True, default=datetime.datetime(2016, 3, 20, 10, 27, 45, 766388, tzinfo=utc), verbose_name='created at'),
preserve_default=False,
),
]

View File

@ -1,5 +1,6 @@
from django.conf import settings as djsettings
from django.db import models
from django.db.models import query, Q
from django.utils.translation import ugettext_lazy as _
from orchestra.contrib.contacts import settings as contacts_settings
@ -32,6 +33,12 @@ class Queue(models.Model):
super(Queue, self).save(*args, **kwargs)
class TicketQuerySet(query.QuerySet):
def involved_by(self, user, *args, **kwargs):
qset = Q(creator=user) | Q(owner=user) | Q(messages__author=user)
return self.filter(qset, *args, **kwargs).distinct()
class Ticket(models.Model):
HIGH = 'HIGH'
MEDIUM = 'MEDIUM'
@ -65,13 +72,13 @@ class Ticket(models.Model):
queue = models.ForeignKey(Queue, related_name='tickets', null=True, blank=True)
subject = models.CharField(_("subject"), max_length=256)
description = models.TextField(_("description"))
priority = models.CharField(_("priority"), max_length=32, choices=PRIORITIES,
default=MEDIUM)
priority = models.CharField(_("priority"), max_length=32, choices=PRIORITIES, default=MEDIUM)
state = models.CharField(_("state"), max_length=32, choices=STATES, default=NEW)
created_at = models.DateTimeField(_("created"), auto_now_add=True, db_index=True)
updated_at = models.DateTimeField(_("modified"), auto_now=True)
cc = models.TextField("CC", help_text=_("emails to send a carbon copy to"),
blank=True)
cc = models.TextField("CC", help_text=_("emails to send a carbon copy to"), blank=True)
objects = TicketQuerySet.as_manager()
class Meta:
ordering = ['-updated_at']
@ -158,7 +165,7 @@ class Message(models.Model):
related_name='ticket_messages')
author_name = models.CharField(_("author name"), max_length=256, blank=True)
content = models.TextField(_("content"))
created_on = models.DateTimeField(_("created on"), auto_now_add=True)
created_at = models.DateTimeField(_("created at"), auto_now_add=True)
class Meta:
get_latest_by = 'id'

View File

@ -13,8 +13,8 @@ class QueueSerializer(serializers.HyperlinkedModelSerializer):
class MessageSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Message
fields = ('id', 'author', 'author_name', 'content', 'created_on')
read_only_fields = ('author', 'author_name', 'created_on')
fields = ('id', 'author', 'author_name', 'content', 'created_at')
read_only_fields = ('author', 'author_name', 'created_at')
def get_identity(self, data):
return data.get('id')

View File

@ -18,7 +18,7 @@ Issue #{{ ticket.id }} has been updated by {{ ticket_message.author }}.
-----------------------------------------------------------------
Issue #{{ ticket.pk }}: {{ ticket.subject }}
* Author: {{ ticket.created_by }}
* Author: {{ ticket.creator_name }}
* Status: {{ ticket.get_state_display }}
* Priority: {{ ticket.get_priority_display }}
* Visibility: {{ ticket.get_visibility_display }}

View File

@ -41,7 +41,7 @@ Issue #{{ ticket.id }} has been updated by {{ ticket_message.author }}.
<h1><a href="http://{{ site.domain }}{% url 'admin:issues_ticket_change' ticket.id %}">Issue #{{ ticket.pk }}: {{ ticket.subject }}</a></h1>
<ul>
<li>Author: {{ ticket.created_by }}</li>
<li>Author: {{ ticket.creator_name }}</li>
<li>Status: {{ ticket.get_state_display }}</li>
<li>Priority: {{ ticket.get_priority_display }}</li>
<li>Visibility: {{ ticket.get_visibility_display }}</li>

View File

@ -4,7 +4,7 @@ from django.contrib.auth.admin import UserAdmin
from django.utils.translation import ugettext_lazy as _
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
from orchestra.admin.actions import disable
from orchestra.admin.actions import disable, enable
from orchestra.admin.utils import admin_link
from orchestra.contrib.accounts.actions import list_accounts
from orchestra.contrib.accounts.admin import SelectAccountAdminMixin
@ -58,7 +58,7 @@ class ListAdmin(ChangePasswordAdminMixin, SelectAccountAdminMixin, ExtendedModel
add_form = ListCreationForm
list_select_related = ('account', 'address_domain',)
filter_by_account_fields = ['address_domain']
actions = (disable, list_accounts)
actions = (disable, enable, list_accounts)
address_domain_link = admin_link('address_domain', order='address_domain__name')

View File

@ -10,7 +10,7 @@ from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
from orchestra.admin.actions import disable
from orchestra.admin.actions import disable, enable
from orchestra.admin.utils import admin_link, change_url
from orchestra.contrib.accounts.actions import list_accounts
from orchestra.contrib.accounts.admin import SelectAccountAdminMixin
@ -74,7 +74,7 @@ class MailboxAdmin(ChangePasswordAdminMixin, SelectAccountAdminMixin, ExtendedMo
add_form = MailboxCreationForm
form = MailboxChangeForm
list_prefetch_related = ('addresses__domain',)
actions = (disable, list_accounts)
actions = (disable, enable, list_accounts)
def __init__(self, *args, **kwargs):
super(MailboxAdmin, self).__init__(*args, **kwargs)

View File

@ -3,7 +3,7 @@ from django.core.exceptions import ObjectDoesNotExist
from django.utils.translation import ugettext_lazy as _
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
from orchestra.admin.actions import disable
from orchestra.admin.actions import disable, enable
from orchestra.admin.utils import change_url
from orchestra.contrib.accounts.actions import list_accounts
from orchestra.contrib.accounts.admin import AccountAdminMixin
@ -24,7 +24,7 @@ class SaaSAdmin(SelectPluginAdminMixin, ChangePasswordAdminMixin, AccountAdminMi
plugin = SoftwareService
plugin_field = 'service'
plugin_title = 'Software as a Service'
actions = (disable, list_accounts)
actions = (disable, enable, list_accounts)
def display_url(self, saas):
site_domain = saas.get_site_domain()

View File

@ -21,6 +21,7 @@ class DrupalMuController(ServiceController):
def save(self, webapp):
context = self.get_context(webapp)
# TODO set password
self.append(textwrap.dedent("""\
mkdir %(drupal_path)s
chown -R www-data %(drupal_path)s
@ -35,6 +36,7 @@ class DrupalMuController(ServiceController):
def delete(self, webapp):
context = self.get_context(webapp)
# TODO delete tables
self.append("rm -fr %(app_path)s" % context)
def get_context(self, webapp):

View File

@ -22,8 +22,9 @@ class WordpressMuController(ServiceController):
model = 'saas.SaaS'
default_route_match = "saas.service == 'wordpress'"
doc_settings = (settings,
('SAAS_WORDPRESS_ADMIN_PASSWORD', 'SAAS_WORDPRESS_MAIN_URL')
('SAAS_WORDPRESS_ADMIN_PASSWORD', 'SAAS_WORDPRESS_MAIN_URL', 'SAAS_WORDPRESS_VERIFY_SSL')
)
VERIFY = settings.SAAS_WORDPRESS_VERIFY_SSL
def login(self, session):
main_url = self.get_main_url()
@ -33,9 +34,10 @@ class WordpressMuController(ServiceController):
'pwd': settings.SAAS_WORDPRESS_ADMIN_PASSWORD,
'redirect_to': '/wp-admin/'
}
response = session.post(login_url, data=login_data)
sys.stdout.write("Login URL: %s\n" % login_url)
response = session.post(login_url, data=login_data, verify=self.VERIFY)
if response.url != main_url + '/wp-admin/':
raise IOError("Failure login to remote application")
raise IOError("Failure login to remote application (%s)" % login_url)
def get_main_url(self):
main_url = settings.SAAS_WORDPRESS_MAIN_URL
@ -54,7 +56,8 @@ class WordpressMuController(ServiceController):
'<a href="http://[\.\-\w]+/wp-admin/network/site-info\.php\?id=([0-9]+)"\s+'
'class="edit">%s</a>' % saas.name
)
content = session.get(search).content.decode('utf8')
sys.stdout.write("Search URL: %s\n" % search)
content = session.get(search, verify=self.VERIFY).content.decode('utf8')
# Get id
ids = regex.search(content)
if not ids and not blog_id:
@ -85,7 +88,8 @@ class WordpressMuController(ServiceController):
except RuntimeError:
url = self.get_main_url()
url += '/wp-admin/network/site-new.php'
content = session.get(url).content.decode('utf8')
sys.stdout.write("Create URL: %s\n" % url)
content = session.get(url, verify=self.VERIFY).content.decode('utf8')
wpnonce = re.compile('name="_wpnonce_add-blog"\s+value="([^"]*)"')
wpnonce = wpnonce.search(content).groups()[0]
@ -99,7 +103,7 @@ class WordpressMuController(ServiceController):
}
# Validate response
response = session.post(url, data=data)
response = session.post(url, data=data, verify=self.VERIFY)
self.validate_response(response)
blog_id = re.compile(r'<link id="wp-admin-canonical" rel="canonical" href="http(?:[^ ]+)/wp-admin/network/site-new.php\?id=([0-9]+)" />')
content = response.content.decode('utf8')
@ -124,8 +128,9 @@ class WordpressMuController(ServiceController):
delete = self.get_main_url()
delete += '/wp-admin/network/sites.php?action=confirm&action2=deleteblog'
delete += '&id=%d&_wpnonce=%s' % (id, wpnonce)
sys.stdout.write("Search URL: %s\n" % delete)
content = session.get(delete).content.decode('utf8')
content = session.get(delete, verify=self.VERIFY).content.decode('utf8')
wpnonce = re.compile('name="_wpnonce"\s+value="([^"]*)"')
wpnonce = wpnonce.search(content).groups()[0]
data = {
@ -136,7 +141,8 @@ class WordpressMuController(ServiceController):
}
delete = self.get_main_url()
delete += '/wp-admin/network/sites.php?action=deleteblog'
response = session.post(delete, data=data)
sys.stdout.write("Delete URL: %s\n" % delete)
response = session.post(delete, data=data, verify=self.VERIFY)
self.validate_response(response)
def save(self, saas):

View File

@ -1,7 +1,10 @@
from .options import SoftwareService
from .. import settings
class DrupalService(SoftwareService):
name = 'drupal'
verbose_name = "Drupal"
icon = 'orchestra/icons/apps/Drupal.png'
site_domain = settings.SAAS_MOODLE_DOMAIN

View File

@ -65,6 +65,11 @@ SAAS_WORDPRESS_DB_NAME = Setting('SAAS_WORDPRESS_DB_NAME',
help_text=_("Needed for domain mapping when <tt>SAAS_WORDPRESS_ALLOW_CUSTOM_URL</tt> is enabled."),
)
SAAS_WORDPRESS_VERIFY_SSL = Setting('SAAS_WORDPRESS_VERIFY_SSL',
True,
help_text=_("Verify SSL certificate on the HTTP requests performed by the backend."),
)
# DokuWiki
@ -119,6 +124,11 @@ SAAS_DRUPAL_SITES_PATH = Setting('WEBSITES_DRUPAL_SITES_PATH',
'/home/httpd/htdocs/drupal-mu/sites/%(site_name)s',
)
SAAS_DRUPAL_DOMAIN = Setting('SAAS_DRUPAL_DOMAIN',
'%(site_name)s.drupal.{}'.format(ORCHESTRA_BASE_DOMAIN),
help_text="Uses <tt>ORCHESTRA_BASE_DOMAIN</tt> by default.",
)
# PhpList

View File

@ -2,6 +2,7 @@ from django.contrib import admin
from django.utils.translation import ugettext_lazy as _
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
from orchestra.admin.actions import disable, enable
from orchestra.contrib.accounts.actions import list_accounts
from orchestra.contrib.accounts.admin import SelectAccountAdminMixin
from orchestra.contrib.accounts.filters import IsActiveListFilter
@ -42,7 +43,7 @@ class SystemUserAdmin(ChangePasswordAdminMixin, SelectAccountAdminMixin, Extende
form = SystemUserChangeForm
ordering = ('-id',)
change_view_actions = (set_permission, create_link)
actions = (delete_selected, list_accounts) + change_view_actions
actions = (disable, enable, delete_selected, list_accounts) + change_view_actions
def display_main(self, user):
return user.is_main

View File

@ -6,7 +6,7 @@ from django.utils.encoding import force_text
from django.utils.translation import ugettext_lazy as _
from orchestra.admin import ExtendedModelAdmin
from orchestra.admin.actions import disable
from orchestra.admin.actions import disable, enable
from orchestra.admin.utils import admin_link, change_url
from orchestra.contrib.accounts.actions import list_accounts
from orchestra.contrib.accounts.admin import AccountAdminMixin, SelectAccountAdminMixin
@ -76,7 +76,7 @@ class WebsiteAdmin(SelectAccountAdminMixin, ExtendedModelAdmin):
filter_by_account_fields = ['domains']
list_prefetch_related = ('domains', 'content_set__webapp')
search_fields = ('name', 'account__username', 'domains__name', 'content__webapp__name')
actions = (disable, list_accounts)
actions = (disable, enable, list_accounts)
def display_domains(self, website):
domains = []