Skip to content

Commit

Permalink
DNS record conversion, fixies, new emails, ..
Browse files Browse the repository at this point in the history
  • Loading branch information
by-cx committed Jan 29, 2013
1 parent 7d593b6 commit 157576f
Show file tree
Hide file tree
Showing 9 changed files with 175 additions and 41 deletions.
13 changes: 7 additions & 6 deletions pcp_runner.py
Expand Up @@ -28,15 +28,16 @@ def run(cmd, stdin=None):
def main():
requests = json.loads(sys.stdin.read().strip())
for request in requests:
log(request)
if request["type"] == "cmd":
cmd = request["cmd"]
if request.get("user"):
cmd = "su %s -c '%s'" % (request.get("user"), cmd)
ret_code, stdout, stderr = run(cmd, request.get("stdin") if request.get("stdin") else None)
request["status"] = "ok"
request["stdout"] = stdout
request["stderr"] = stderr
request["ret_code"] = ret_code
ret_code, stdout, stderr = run(cmd, request.get("stdin") if request.get("stdin") else None)
request["status"] = "ok"
request["stdout"] = stdout
request["stderr"] = stderr
request["ret_code"] = ret_code
if request.get("rm_stdin"):
request["stdin"] = ""
#if ret_code != 0:
Expand All @@ -56,4 +57,4 @@ def main():
try:
main()
except OSError as e:
log("[exception]: OSError (%s)" % e.message)
print "OSError (%s)" % e
12 changes: 7 additions & 5 deletions sql/init.sql
Expand Up @@ -10,14 +10,16 @@ CREATE VIEW mailboxes AS
SELECT
e.login||'@'||d.name AS email,
password,
100 AS uid,
100 AS gid,
'/var/www/' AS homedir,
117 AS uid,
118 AS gid,
'/var/mail' AS homedir,
d.name||'/'||e.login||'/' AS maildir,
'/var/www'||'/'||d.name||'/'||e.login||'/' AS dir,
'/var/mail'||'/'||d.name||'/'||e.login||'/' AS dir,
e.login AS name
FROM
emails_email e,
emails_domain d
WHERE
e.domain_id = d.id;
e.domain_id = d.id;

SELECT alias||'@'||d.name AS alias, email, 'f' AS trash FROM emails_redirect r, emails_domain d WHERE r.domain_id = d.id;
4 changes: 2 additions & 2 deletions wsgiadmin/apps/tools.py
Expand Up @@ -36,8 +36,6 @@ def send(self, cmd, stdin=None):
logging.info("[stdin]: %s" % stdin)
p = Popen(["ssh", self.server]+cmd, stdout=PIPE, stderr=PIPE, stdin=PIPE)
stdout, stderr = p.communicate(stdin)
if not stderr:
return json.loads(stdout)
if settings.DEBUG:
if stdout:
sys.stdout.write("[stdout]: %s\n" % stdout)
Expand All @@ -46,6 +44,8 @@ def send(self, cmd, stdin=None):
sys.stdout.write("[stderr]: %s\n" % stderr)
logging.info("[stderr]: %s" % stderr)
sys.stdout.write("---\n")
if not stderr:
return json.loads(stdout)
raise ScriptException("PCP runner script error: %s" % stderr)

def commit(self, no_thread=False):
Expand Down
125 changes: 125 additions & 0 deletions wsgiadmin/dns/migrations/0006_convert_from_domains.py
@@ -0,0 +1,125 @@
# -*- coding: utf-8 -*-
import datetime
from constance import config
from django.contrib.auth.models import User
from south.db import db
from south.v2 import DataMigration
from django.db import models
from wsgiadmin.domains.models import Domain

class Migration(DataMigration):

def default_records(self, orm, domain):
record = orm['dns.record']()
record.name = "@"
record.record_type = "A"
record.value = config.dns_default_a
record.ttl = config.dns_default_record_ttl
record.domain = domain
record.order_num = 2
record.save()

record = orm['dns.record']()
record.name = "@"
record.record_type = "AAAA"
record.value = config.dns_default_aaaa
record.ttl = config.dns_default_record_ttl
record.domain = domain
record.order_num = 3
record.save()

record = orm['dns.record']()
record.name = "@"
record.record_type = "MX"
record.value = config.dns_default_mx
record.ttl = config.dns_default_record_ttl
record.domain = domain
record.order_num = 1
record.save()

record = orm['dns.record']()
record.name = "www"
record.record_type = "CNAME"
record.value = "@"
record.ttl = config.dns_default_record_ttl
record.domain = domain
record.order_num = 4
record.save()

def forwards(self, orm):
#TODO: this is really ugly and wont work in the future
for domain in Domain.objects.all():
if not domain.parent and domain.dns:
dns = orm['dns.domain']()
dns.name = domain.name
dns.rname = "info@rosti.cz"
dns.user = orm['auth.User'].objects.get(id=domain.owner.id)
dns.save()
self.default_records(orm, dns)
print "\tDomain %s converted to dns" % domain.name

def backwards(self, orm):
raise RuntimeError("Cannot reverse this migration.")

models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'dns.domain': {
'Meta': {'object_name': 'Domain'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'last_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '256'}),
'rname': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
'serial': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'ttl': ('django.db.models.fields.IntegerField', [], {'default': '86400'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'dns_set'", 'to': "orm['auth.User']"})
},
'dns.record': {
'Meta': {'object_name': 'Record'},
'domain': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dns.Domain']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'default': "'@'", 'max_length': '256'}),
'order_num': ('django.db.models.fields.IntegerField', [], {}),
'prio': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'record_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
'ttl': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'value': ('django.db.models.fields.CharField', [], {'max_length': '256'})
}
}

complete_apps = ['dns']
symmetrical = True
14 changes: 7 additions & 7 deletions wsgiadmin/emails/backend.py
Expand Up @@ -10,18 +10,18 @@ def install(self, email):
homedir = join(config.maildir, email.domain.name)
maildir = join(homedir, email.login)

self.script.add_cmd("mkdir -p %s" % homedir)
self.script.add_cmd("chown email:email %s -R" % homedir)
self.script.add_cmd("maildirmake %s" % maildir)
self.script.add_cmd("chown email:email %s -R" % maildir)
self.script.add_cmd("maildirmake %s" % join(maildir, '.Spam'))
self.script.add_cmd("chown email:email %s -R" % join(maildir, 'Spam'))
self.script.add_cmd("mkdir -p '%s'" % homedir)
self.script.add_cmd("chown email:email '%s' -R" % homedir)
self.script.add_cmd("maildirmake '%s'" % maildir)
self.script.add_cmd("chown email:email '%s' -R" % maildir)
self.script.add_cmd("maildirmake '%s'" % join(maildir, '.Spam'))
self.script.add_cmd("chown email:email '%s' -R" % join(maildir, 'Spam'))

def commit(self):
self.script.commit()

def uninstall(self, email):
maildir = join(config.maildir, email.domain.domain_name, email.login)
maildir = join(config.maildir, email.domain.name, email.login)
self.script.add_cmd("rm -rf %s" % maildir)

def uninstall_domain(self, domain):
Expand Down
9 changes: 8 additions & 1 deletion wsgiadmin/emails/forms.py
@@ -1,6 +1,7 @@
from django import forms
from django.forms.models import ModelForm
from django.utils.translation import ugettext_lazy as _
import re

from wsgiadmin.emails.models import Email, EmailRedirect, Domain
from wsgiadmin.service.forms import PassCheckModelForm, RostiFormHelper
Expand All @@ -15,8 +16,10 @@ class Meta:
fields = ("login", "xdomain", "password1", "password2")

def clean_login(self):
if Email.objects.filter(remove=False, domain__name=self.data['xdomain'], login=self.cleaned_data["login"]).count():
if Email.objects.filter(domain__name=self.data['xdomain'], login=self.cleaned_data["login"]).count():
raise forms.ValidationError(_("Given username already exists"))
if not re.match("^[0-9a-zA-Z_\.]*$", self.cleaned_data["login"]):
raise forms.ValidationError(_("Login has to be in this format: ^[0-9a-zA-Z_\.]*$"))

return self.cleaned_data["login"]

Expand Down Expand Up @@ -49,5 +52,9 @@ class Meta:
model = Domain
fields = ("name", )

def clean_name(self):
if not re.match("^[0-9a-zA-Z\.]*$", self.cleaned_data["name"]):
raise forms.ValidationError(_("Domain name has to be in this format: ^[0-9a-zA-Z\.]*$"))

def clean_user(self):
return None
31 changes: 15 additions & 16 deletions wsgiadmin/emails/views.py
Expand Up @@ -79,7 +79,7 @@ def addBox(request):
u = request.session.get('switched_user', request.user)
superuser = request.user

domains = [(x.name, x.name) for x in u.email_domain_set.filter(mail=True)]
domains = [(x.name, x.name) for x in u.email_domain_set.all()]

if request.method == 'POST':
form = FormEmail(request.POST)
Expand Down Expand Up @@ -123,23 +123,22 @@ def addBox(request):

@login_required
def mailbox_remove(request):
object_id = request.GET['pk']
u = request.session.get('switched_user', request.user)

try:
object_id = request.POST['object_id']
u = request.session.get('switched_user', request.user)
mail = Email.objects.get(domain__in=u.email_domain_set.all(), id=object_id)
except EmailRedirect.DoesNotExist:
raise Exception("redirect doesn't exist, obviously")

try:
mail = Email.objects.get(domain__in=u.email_domain_set.all(), id=object_id)
except EmailRedirect.DoesNotExist:
raise Exception("redirect doesn't exist, obviously")
else:
backend = EmailBackend()
backend.uninstall(mail)
backend.commit()
mail.delete()
backend = EmailBackend()
backend.uninstall(mail)
backend.commit()
mail.delete()

return JsonResponse("OK", {1: ugettext("Mailbox was successfuly deleted")})
except Exception, e:
return JsonResponse("KO", {1: ugettext("Error during mailbox delete")})
messages.add_message(request, messages.SUCCESS, _('E-mail has been added'))

return HttpResponseRedirect(reverse("mailbox_list"))


@login_required
Expand Down Expand Up @@ -253,7 +252,7 @@ def addRedirect(request):
u = request.session.get('switched_user', request.user)
superuser = request.user

domains = [(x.name, x.name) for x in u.email_domain_set.filter(mail=True)]
domains = [(x.name, x.name) for x in u.email_domain_set.filter()]
if request.method == 'POST':
form = FormRedirect(request.POST)
form.fields["_domain"].choices = domains
Expand Down
6 changes: 3 additions & 3 deletions wsgiadmin/templates/admin.html
Expand Up @@ -15,9 +15,9 @@
<li {% if menu_active == "users" %} class="active"{% endif %}>
<a href="{% url wsgiadmin.users.views.show %}" class="red">{% trans "Users" %}</a>
</li>
<li {% if menu_active == "domains" %} class="active"{% endif %}>
<!--<li {% if menu_active == "domains" %} class="active"{% endif %}>
<a href="{% url domains_list %}">{% trans "Domains" %}</a>
</li>
</li>-->
{% endif %}
<li {% if menu_active == "dns" %} class="active"{% endif %}>
<a href="{% url dns_list %}">{% trans "DNS" %}</a>
Expand Down Expand Up @@ -193,7 +193,7 @@
{% endif %}
{% if menu_active == "emails" %}
<li>
<a href="{% url email_domain_add %}">{% trans "Add domain for mailbox" %}</a>
<a href="{% url email_domain_add %}">{% trans "Add domain for mailboxes" %}</a>
</li>
<li>
<a href="{% url add_mailbox %}">{% trans "Add mailbox" %}</a>
Expand Down
2 changes: 1 addition & 1 deletion wsgiadmin/templates/boxes.html
Expand Up @@ -40,7 +40,7 @@ <h3>{% trans "List of e-mail boxes" %}</h3>
<a href="{% url wsgiadmin.emails.views.changePasswdBox email.id %}" class="btn btn-warning">{% trans "Change password" %}</a>
</li>
<li class="smazat">
<a href="#" class="object_delete btn btn-danger" rel="{{ email.id }}">{% trans "Delete" %}</a>
<a href="#a" class="btn btn-danger" onclick="if(confirm('{% trans "Are you sure?" %}')) document.location='{% url mailbox_remove %}?pk={{ email.id }}';">{% trans "Delete" %}</a>
</li>
</ul>
<span id="removed_{{ email.id }}" class="info"></span>
Expand Down

0 comments on commit 157576f

Please sign in to comment.