Also add a setup.py that's used to validate, and a git hook.
from models import *
+
class VirtualUserForm(forms.ModelForm):
class Meta:
model = VirtualUser
self.user = user
def clean_local_domain(self):
- if not self.instance.pk: return self.cleaned_data['local_domain']
+ if not self.instance.pk:
+ return self.cleaned_data['local_domain']
if self.cleaned_data['local_domain'] != self.instance.local_domain:
raise ValidationError("Can't change local domain!")
return self.cleaned_data['local_domain']
-
+
def clean_local_part(self):
- if not self.instance.pk: return self.cleaned_data['local_part']
+ if not self.instance.pk:
+ return self.cleaned_data['local_part']
if self.cleaned_data['local_part'] != self.instance.local_part:
raise ValidationError("Renaming accounts is not possible - you have to delete and add!")
return self.cleaned_data['local_part']
# Changing password requires calling pgcrypto. So let's do that...
curs = connection.cursor()
curs.execute("SELECT public.crypt(%(pwd)s, public.gen_salt('md5'))", {
- 'pwd': self.cleaned_data['passwd']
- })
+ 'pwd': self.cleaned_data['passwd']
+ })
return curs.fetchall()[0][0]
-
+
return self.cleaned_data['passwd']
def clean(self):
- if not self.cleaned_data.has_key('local_part'):
+ if 'local_part' not in self.cleaned_data:
return {}
# Validate that the pattern is allowed
curs = connection.cursor()
curs.execute("SELECT 1 FROM mailmgr_userpermissions WHERE user_id=%(uid)s AND domain_id=%(domain)s AND %(lp)s ~* ('^'||pattern||'$')", {
- 'uid': self.user.pk,
- 'domain': self.cleaned_data['local_domain'].pk,
- 'lp': self.cleaned_data['local_part'],
- })
+ 'uid': self.user.pk,
+ 'domain': self.cleaned_data['local_domain'].pk,
+ 'lp': self.cleaned_data['local_part'],
+ })
perms = curs.fetchall()
if len(perms) < 1:
return self.cleaned_data
-
class ForwarderForm(forms.ModelForm):
class Meta:
model = Forwarder
self.user = user
def clean_local_domain(self):
- if not self.instance.pk: return self.cleaned_data['local_domain']
+ if not self.instance.pk:
+ return self.cleaned_data['local_domain']
if self.cleaned_data['local_domain'] != self.instance.local_domain:
raise ValidationError("Can't change local domain!")
return self.cleaned_data['local_domain']
-
+
def clean_local_part(self):
- if not self.instance.pk: return self.cleaned_data['local_part']
+ if not self.instance.pk:
+ return self.cleaned_data['local_part']
if self.cleaned_data['local_part'] != self.instance.local_part:
raise ValidationError("Renaming forwarders is not possible - you have to delete and add!")
return self.cleaned_data['local_part']
def clean(self):
- if not self.cleaned_data.has_key('local_part'):
+ if 'local_part' not in self.cleaned_data:
return {}
# Validate that the pattern is allowed
curs = connection.cursor()
curs.execute("SELECT 1 FROM mailmgr_userpermissions WHERE user_id=%(uid)s AND domain_id=%(domain)s AND %(lp)s ~* ('^'||pattern||'$')", {
- 'uid': self.user.pk,
- 'domain': self.cleaned_data['local_domain'].pk,
- 'lp': self.cleaned_data['local_part'],
- })
+ 'uid': self.user.pk,
+ 'domain': self.cleaned_data['local_domain'].pk,
+ 'lp': self.cleaned_data['local_part'],
+ })
perms = curs.fetchall()
if len(perms) < 1:
from django.contrib.auth.models import User
from django.db.models import signals
+
class LocalDomain(models.Model):
local_domain_id = models.AutoField(null=False, primary_key=True)
domain_name = models.CharField(max_length=100, null=False, blank=False)
return self.domain_name
trigger_update = True
+
class Meta:
- ordering=('domain_name',)
- db_table='mail"."local_domains'
- managed=False
+ ordering = ('domain_name',)
+ db_table = 'mail"."local_domains'
+ managed = False
+
class Forwarder(models.Model):
forwarder_id = models.AutoField(null=False, primary_key=True)
return "%s@%s -> %s" % (self.local_part, self.local_domain.domain_name, self.remote_name)
trigger_update = True
+
class Meta:
- ordering=('local_part',)
- db_table='mail"."forwarder'
- managed=False
+ ordering = ('local_part',)
+ db_table = 'mail"."forwarder'
+ managed = False
+
class VirtualUser(models.Model):
virtual_user_id = models.AutoField(null=False, primary_key=True)
return "%s@%s (%s)" % (self.local_part, self.local_domain.domain_name, self.full_name or '')
trigger_update = True
+
class Meta:
- ordering=('local_part',)
- db_table='mail"."virtual_user'
- managed=False
- unique_together=('local_domain', 'local_part', )
+ ordering = ('local_part',)
+ db_table = 'mail"."virtual_user'
+ managed = False
+ unique_together = ('local_domain', 'local_part', )
class UserPermissions(models.Model):
def __unicode__(self):
return "%s -> %s pattern '%s'" % (self.user, self.domain, self.pattern)
+
class Log(models.Model):
user = models.ForeignKey(User, null=False)
when = models.DateTimeField(null=False, auto_now=True)
return "%s (%s): %s" % (self.when, self.user, self.what)
class Meta:
- ordering=('-when',)
+ ordering = ('-when',)
+
def pgmail_save_handler(sender, **kwargs):
if hasattr(sender, 'trigger_update') and sender.trigger_update:
with open('/tmp/.mailmgr_update', 'w') as f:
pass
+
signals.post_save.connect(pgmail_save_handler)
from models import *
from forms import *
+
def log(user, what):
l = Log()
l.user = user
l.what = what
l.save()
+
@login_required
def home(request):
users = VirtualUser.objects.extra(where=["EXISTS (SELECT 1 FROM mailmgr_userpermissions p WHERE p.user_id=%s AND p.domain_id = local_domain_id AND local_part ~* ('^'||p.pattern||'$'))" % request.user.id])
forwards = Forwarder.objects.extra(where=["EXISTS (SELECT 1 FROM mailmgr_userpermissions p WHERE p.user_id=%s AND p.domain_id = local_domain_id AND local_part ~* ('^'||p.pattern||'$'))" % request.user.id])
return render(request, 'home.html', {
- 'users': users,
- 'forwarders': forwards,
- })
+ 'users': users,
+ 'forwarders': forwards,
+ })
+
@transaction.atomic
@login_required
if request.method == 'POST':
form = VirtualUserForm(data=request.POST, instance=vu, user=request.user)
if request.POST['passwd'] != vu.passwd:
- password_changed=True
+ password_changed = True
else:
- password_changed=False
+ password_changed = False
if form.is_valid():
form.save()
messages.add_message(request, messages.INFO, 'User %s updated' % vu)
if password_changed:
messages.add_message(request, messages.INFO, 'Password changed for user %s' % vu)
- log(request.user, "%s user %s, including changing the password" % (userparam=='add' and 'Added' or 'Updated', vu))
+ log(request.user, "%s user %s, including changing the password" % (userparam == 'add' and 'Added' or 'Updated', vu))
else:
- log(request.user, "%s user %s, without changing the password" % (userparam=='add' and 'Added' or 'Updated', vu))
+ log(request.user, "%s user %s, without changing the password" % (userparam == 'add' and 'Added' or 'Updated', vu))
return HttpResponseRedirect('/')
else:
# Generate a new form
form = VirtualUserForm(instance=vu, user=request.user)
- return render(request,'form.html', {
- 'form': form,
- 'savebutton': (userparam == 'new') and "New" or "Save"
- })
+ return render(request, 'form.html', {
+ 'form': form,
+ 'savebutton': (userparam == 'new') and "New" or "Save"
+ })
+
@transaction.atomic
@login_required
form = ForwarderForm(data=request.POST, instance=fwd, user=request.user)
if form.is_valid():
form.save()
- log(request.user, "%s forwarding %s -> %s" % (userparam=='add' and 'Added' or 'Updated', fwd, fwd.remote_name))
+ log(request.user, "%s forwarding %s -> %s" % (userparam == 'add' and 'Added' or 'Updated', fwd, fwd.remote_name))
messages.add_message(request, messages.INFO, 'Forwarder %s updated' % fwd)
return HttpResponseRedirect('/')
else:
form = ForwarderForm(instance=fwd, user=request.user)
return render(request, 'form.html', {
- 'form': form,
- 'savebutton': (userparam == 'new') and "New" or "Save"
- })
-
+ 'form': form,
+ 'savebutton': (userparam == 'new') and "New" or "Save"
+ })
DATABASES = {
'default': {
- 'ENGINE': 'django.db.backends.postgresql_psycopg2', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
+ 'ENGINE': 'django.db.backends.postgresql_psycopg2', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
'NAME': 'pgmail', # Or path to database file if using sqlite3.
'USER': 'pgmail', # Not used with sqlite3.
'PASSWORD': '', # Not used with sqlite3.
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
-# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
)
# Make this unique, and don't share it with anybody.
-#SECRET_KEY lives in settings_local.py
-
+# SECRET_KEY lives in settings_local.py
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'pgmailmgr.auth.AuthBackend',
)
-DEBUG=False
-SESSION_COOKIE_SECURE= True
-SESSION_COOKIE_DOMAIN="webmail.postgresql.org"
+DEBUG = False
+SESSION_COOKIE_SECURE = True
+SESSION_COOKIE_DOMAIN = "webmail.postgresql.org"
+
from settings_local import *
from django.conf.urls import include, url
+import pgmailmgr.mailmgr.views as views
+import pgmailmgr.auth
+
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()
-import pgmailmgr.mailmgr.views as views
-import pgmailmgr.auth
-
urlpatterns = [
url(r'^$', views.home),
url(r'^user/(\d+|add)/$', views.userform),
--- /dev/null
+[pycodestyle]
+statistics=True
+ignore=E402,E501,E741
+max-line-length=120
--- /dev/null
+#!/bin/sh
+
+if git rev-parse --verify HEAD >/dev/null 2>&1
+then
+ against=HEAD
+else
+ # Initial commit: diff against an empty tree object
+ against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
+fi
+
+FILES=$(git diff-index --name-only --diff-filter=ACMR --cached $against -- |egrep ".py$")
+if [ "$FILES" != "" ]; then
+ # We want to look at the staged version only, so we have to run it once for
+ # each file.
+ E=0
+ for F in ${FILES}; do
+ P=$(git show ":$F" | python -c "import sys; compile(sys.stdin.read(), '/dev/null', 'exec')")
+ if [ "$?" != "0" ]; then
+ echo "Errors in $F"
+ echo $P
+ E=1
+ continue
+ fi
+
+ R=$(git show ":$F" | pep8 -)
+ if [ "$?" != "0" ]; then
+ echo "Errors in $F"
+ echo "$R"
+ E=1
+ fi
+ done
+ if [ "$E" != "0" ]; then
+ exit 1
+ fi
+
+ echo Basic python checks passed.
+fi
+