diff --git a/mailadmin/api.py b/mailadmin/api.py
index ace8d76..0a4d550 100644
--- a/mailadmin/api.py
+++ b/mailadmin/api.py
@@ -1,5 +1,18 @@
import requests
from django.conf import settings
+import logging
+from rest_framework import exceptions
+
+logger = logging.getLogger(__name__)
+
+
+class DPDAPIException(exceptions.APIException):
+ status_code = 503
+ detail = 'Unknown error.'
+
+ def __init__(self, status_code, detail):
+ self.status_code = status_code
+ self.detail = detail
class DjangoPostfixDovecotAPI(object):
@@ -26,7 +39,11 @@ class DjangoPostfixDovecotAPI(object):
json=json,
headers=headers)
- r.raise_for_status()
+ try:
+ r.raise_for_status()
+ except requests.exceptions.RequestException as e:
+ logger.warning('mxapi errored {}'.format(e.response))
+ raise DPDAPIException(status_code=e.response.status_code, detail=e.response.json())
return r.json()
@@ -46,4 +63,16 @@ class DjangoPostfixDovecotAPI(object):
'GET',
'/aliases/',
params=params
+ )
+
+ def list_domains(self, name=None):
+ params = {}
+
+ if name is not None:
+ params['name'] = name
+
+ return self._api(
+ 'GET',
+ '/domains/',
+ params=params
)
\ No newline at end of file
diff --git a/mailadmin/serializers.py b/mailadmin/serializers.py
index 7422923..94f8fdc 100644
--- a/mailadmin/serializers.py
+++ b/mailadmin/serializers.py
@@ -30,11 +30,13 @@ class OrgUnitSerializer(serializers.ModelSerializer):
class AliasSerializer(serializers.Serializer):
source = serializers.EmailField(required=True)
destination = serializers.EmailField(required=True)
- _domain_name = settings.NEUF_EMAIL_DOMAIN_NAME
+ domain = serializers.IntegerField(required=True)
- def validate_destonation(self, attrs, source):
- domain_part = attrs[source].split('@')[1]
- if domain_part != self._domain_name:
- raise serializers.ValidationError("dest '{0}' is not in domain {1}".format(attrs[source], self._domain_name))
+ def validate_source(self, value):
+ _domain_name = settings.NEUF_EMAIL_DOMAIN_NAME
- return attrs
\ No newline at end of file
+ domain_part = value.split('@')[1]
+ if domain_part != _domain_name:
+ raise serializers.ValidationError("source '{0}' is not in domain {1}".format(value, _domain_name))
+
+ return value
\ No newline at end of file
diff --git a/mailadmin/static/app/scripts/main.js b/mailadmin/static/app/scripts/main.js
index c786ff7..f514bce 100644
--- a/mailadmin/static/app/scripts/main.js
+++ b/mailadmin/static/app/scripts/main.js
@@ -67,7 +67,8 @@
var api_urls = {
aliases: '/api/aliases/',
ou_list: '/api/orgunits/',
- me: '/api/me/'
+ me: '/api/me/',
+ email_domain: '/api/emaildomain/'
};
var forwards_container = $(".forwards-container");
nunjucks.configure({ autoescape: true });
@@ -87,103 +88,117 @@
$('.orgunit-list li a[data-prefix="'+prefix+'"]').parent().toggleClass('active');
}
- /* New list */
- var new_list_html = nunjucks.render('new_list.html', {
- orgunits: data,
- api_urls: api_urls
- });
+ $.getJSON(api_urls.email_domain, function(email_domain) {
+ email_domain = email_domain.domain;
+ console.log(email_domain);
-
- $('.new-list').html(new_list_html);
- $('.new-list .js-new-list-name').on('keyup', function() {
- var new_list_name = $('.new-list .js-new-list-name').val();
- if(new_list_name === '') {
- new_list_name = 'Ny liste';
- } else {
- var prefix = $('.new-list .prefix-select .active').attr('data-value');
- new_list_name = 'NY: ' + prefix + new_list_name + "@studentersamfundet.no";
- }
- $('.js-new-list-preview').text(new_list_name);
- });
- /* Prefix select */
- $('.new-list .prefix-select a').on('click', function() {
- $('.new-list .prefix-select a').parent().removeClass('active');
- $(this).parent().addClass('active');
- var prefix = $(this).parent().attr('data-value');
- $('.new-list .prefix-btn').html(prefix+' ');
- });
- // TODO put this in a function with selector as argument
- $('.new-list textarea').on('keyup', function() {
- var text = $(this).val();
- var emails = parseEmails(text);
-
- if(emails.length > 0) {
- $('.new-list .email-counter').text(emails.length);
- } else {
- $('.new-list .email-counter').text('');
- }
- });
- $('.js-add-list').on('click', function(e) {
- $('.new-list .result').html(''); // reset errors
- e.preventDefault();
- /* Validate */
- var new_list_name = $('.new-list .js-new-list-name').val();
- if(new_list_name.length === 0) {
- notify('Ny epostliste', 'Navn på epostliste mangler', 'error');
- return;
- }
- var text = $('.new-list textarea').val();
- var emails = parseEmails(text);
- if(emails.length === 0) {
- notify('Ny epostliste', 'Ingen eposter i epost-feltet...', 'error');
- return;
- }
- // Valid form
- var prefix = $('.new-list .prefix-select .active').attr('data-value');
- var dest = prefix + new_list_name + "@studentersamfundet.no";
-
- var new_list = {};
- new_list[dest] = _.map(emails, function(el) {
- return {'dest': dest, 'forward': el};
+ /* New list */
+ var new_list_html = nunjucks.render('new_list.html', {
+ orgunits: data,
+ api_urls: api_urls,
+ email_domain: email_domain
});
- $.post(
- api_urls.aliases,
- new_list[dest],
- function() {
- notify('Lagt til', 'Ny liste: ' + dest + 'lagt til', 'success');
+
+ $('.new-list').html(new_list_html);
+ $('.new-list .js-new-list-name').on('keyup', function() {
+ var new_list_name = $('.new-list .js-new-list-name').val();
+ if(new_list_name === '') {
+ new_list_name = 'Ny liste';
+ } else {
+ var prefix = $('.new-list .prefix-select .active').attr('data-value');
+ new_list_name = 'NY: ' + prefix + new_list_name + "@" + email_domain.name;
+ }
+ $('.js-new-list-preview').text(new_list_name);
+ });
+ /* Prefix select */
+ $('.new-list .prefix-select a').on('click', function() {
+ $('.new-list .prefix-select a').parent().removeClass('active');
+ $(this).parent().addClass('active');
+ var prefix = $(this).parent().attr('data-value');
+ $('.new-list .prefix-btn').html(prefix+' ');
+ });
+ // TODO put this in a function with selector as argument
+ $('.new-list textarea').on('keyup', function() {
+ var text = $(this).val();
+ var emails = parseEmails(text);
+
+ if(emails.length > 0) {
+ $('.new-list .email-counter').text(emails.length);
+ } else {
+ $('.new-list .email-counter').text('');
+ }
+ });
+ $('.js-add-list').on('click', function(e) {
+ e.preventDefault();
+ /* Validate */
+ var new_list_name = $('.new-list .js-new-list-name').val();
+ if(new_list_name.length === 0) {
+ notify('Ny epostliste', 'Navn på epostliste mangler', 'error');
+ return;
+ }
+ var text = $('.new-list textarea').val();
+ var emails = parseEmails(text);
+ if(emails.length === 0) {
+ notify('Ny epostliste', 'Ingen eposter i epost-feltet...', 'error');
+ return;
+ }
+ // Valid form
+ var prefix = $('.new-list .prefix-select .active').attr('data-value');
+ var source = prefix + new_list_name + "@" + email_domain.name;
+
+ var new_aliases = {};
+ new_aliases = _.map(emails, function(el) {
+ return {
+ 'source': source,
+ 'destination': el,
+ 'domain': email_domain.id
+ };
+ });
+ console.log(new_aliases);
+ $.ajax({
+ url: api_urls.aliases,
+ type: 'POST',
+ headers: {'X-CSRFToken': csrf_token},
+ dataType: 'json',
+ contentType: "application/json; charset=utf-8",
+ data: JSON.stringify(new_aliases),
+
+ }).done(function(resp) {
+ console.log(resp);
+ notify('Lagt til', 'Ny liste: ' + source + ' lagt til', 'success');
$('.new-list textarea').val('');
$('.new-list .js-new-list-name').val('');
- },
- 'json'
- );
- var added_list_html = nunjucks.render('list.html', { lists: new_list });
- forwards_container.prepend(added_list_html);
+ // FIXME: Existing list?
+ var added_list_html = nunjucks.render('list.html', { lists: new_aliases });
+ forwards_container.prepend(added_list_html);
+ });
- });
+ });
- /* Filter lists by orgunit */
- $(".orgunit-list a").on('click', function(e) {
- var prefix = $(this).attr('data-prefix');
- e.preventDefault();
+ /* Filter lists by orgunit */
+ $(".orgunit-list a").on('click', function(e) {
+ var prefix = $(this).attr('data-prefix');
+ e.preventDefault();
- /* Toggle selection */
- $(".orgunit-list li").removeClass('active');
- $(this).parent().toggleClass('active');
- $('.orgunits-select').val(prefix);
+ /* Toggle selection */
+ $(".orgunit-list li").removeClass('active');
+ $(this).parent().toggleClass('active');
+ $('.orgunits-select').val(prefix);
- filter_lists('^'+prefix+'-', true);
- $('.js-lists-filter-field').val('');
- });
- $(".orgunits-select").on('change', function() {
- var prefix = $(this).val();
+ filter_lists('^'+prefix+'-', true);
+ $('.js-lists-filter-field').val('');
+ });
+ $(".orgunits-select").on('change', function() {
+ var prefix = $(this).val();
- /* Toggle selection */
- $(".orgunit-list li").removeClass('active');
- $(".orgunit-list li a[data-prefix="+prefix+"]").parent().toggleClass('active');
+ /* Toggle selection */
+ $(".orgunit-list li").removeClass('active');
+ $(".orgunit-list li a[data-prefix="+prefix+"]").parent().toggleClass('active');
- filter_lists('^'+prefix+'-', true);
- $('.js-lists-filter-field').val('');
+ filter_lists('^'+prefix+'-', true);
+ $('.js-lists-filter-field').val('');
+ });
});
});
diff --git a/mailadmin/static/app/templates/new_list.html b/mailadmin/static/app/templates/new_list.html
index 591296b..eb104c0 100644
--- a/mailadmin/static/app/templates/new_list.html
+++ b/mailadmin/static/app/templates/new_list.html
@@ -11,7 +11,7 @@
- @studentersamfundet.no
+ @{{email_domain.name}}
Eposter
diff --git a/mailadmin/static/dist/scripts/main.js b/mailadmin/static/dist/scripts/main.js
index c786ff7..f514bce 100644
--- a/mailadmin/static/dist/scripts/main.js
+++ b/mailadmin/static/dist/scripts/main.js
@@ -67,7 +67,8 @@
var api_urls = {
aliases: '/api/aliases/',
ou_list: '/api/orgunits/',
- me: '/api/me/'
+ me: '/api/me/',
+ email_domain: '/api/emaildomain/'
};
var forwards_container = $(".forwards-container");
nunjucks.configure({ autoescape: true });
@@ -87,103 +88,117 @@
$('.orgunit-list li a[data-prefix="'+prefix+'"]').parent().toggleClass('active');
}
- /* New list */
- var new_list_html = nunjucks.render('new_list.html', {
- orgunits: data,
- api_urls: api_urls
- });
+ $.getJSON(api_urls.email_domain, function(email_domain) {
+ email_domain = email_domain.domain;
+ console.log(email_domain);
-
- $('.new-list').html(new_list_html);
- $('.new-list .js-new-list-name').on('keyup', function() {
- var new_list_name = $('.new-list .js-new-list-name').val();
- if(new_list_name === '') {
- new_list_name = 'Ny liste';
- } else {
- var prefix = $('.new-list .prefix-select .active').attr('data-value');
- new_list_name = 'NY: ' + prefix + new_list_name + "@studentersamfundet.no";
- }
- $('.js-new-list-preview').text(new_list_name);
- });
- /* Prefix select */
- $('.new-list .prefix-select a').on('click', function() {
- $('.new-list .prefix-select a').parent().removeClass('active');
- $(this).parent().addClass('active');
- var prefix = $(this).parent().attr('data-value');
- $('.new-list .prefix-btn').html(prefix+' ');
- });
- // TODO put this in a function with selector as argument
- $('.new-list textarea').on('keyup', function() {
- var text = $(this).val();
- var emails = parseEmails(text);
-
- if(emails.length > 0) {
- $('.new-list .email-counter').text(emails.length);
- } else {
- $('.new-list .email-counter').text('');
- }
- });
- $('.js-add-list').on('click', function(e) {
- $('.new-list .result').html(''); // reset errors
- e.preventDefault();
- /* Validate */
- var new_list_name = $('.new-list .js-new-list-name').val();
- if(new_list_name.length === 0) {
- notify('Ny epostliste', 'Navn på epostliste mangler', 'error');
- return;
- }
- var text = $('.new-list textarea').val();
- var emails = parseEmails(text);
- if(emails.length === 0) {
- notify('Ny epostliste', 'Ingen eposter i epost-feltet...', 'error');
- return;
- }
- // Valid form
- var prefix = $('.new-list .prefix-select .active').attr('data-value');
- var dest = prefix + new_list_name + "@studentersamfundet.no";
-
- var new_list = {};
- new_list[dest] = _.map(emails, function(el) {
- return {'dest': dest, 'forward': el};
+ /* New list */
+ var new_list_html = nunjucks.render('new_list.html', {
+ orgunits: data,
+ api_urls: api_urls,
+ email_domain: email_domain
});
- $.post(
- api_urls.aliases,
- new_list[dest],
- function() {
- notify('Lagt til', 'Ny liste: ' + dest + 'lagt til', 'success');
+
+ $('.new-list').html(new_list_html);
+ $('.new-list .js-new-list-name').on('keyup', function() {
+ var new_list_name = $('.new-list .js-new-list-name').val();
+ if(new_list_name === '') {
+ new_list_name = 'Ny liste';
+ } else {
+ var prefix = $('.new-list .prefix-select .active').attr('data-value');
+ new_list_name = 'NY: ' + prefix + new_list_name + "@" + email_domain.name;
+ }
+ $('.js-new-list-preview').text(new_list_name);
+ });
+ /* Prefix select */
+ $('.new-list .prefix-select a').on('click', function() {
+ $('.new-list .prefix-select a').parent().removeClass('active');
+ $(this).parent().addClass('active');
+ var prefix = $(this).parent().attr('data-value');
+ $('.new-list .prefix-btn').html(prefix+' ');
+ });
+ // TODO put this in a function with selector as argument
+ $('.new-list textarea').on('keyup', function() {
+ var text = $(this).val();
+ var emails = parseEmails(text);
+
+ if(emails.length > 0) {
+ $('.new-list .email-counter').text(emails.length);
+ } else {
+ $('.new-list .email-counter').text('');
+ }
+ });
+ $('.js-add-list').on('click', function(e) {
+ e.preventDefault();
+ /* Validate */
+ var new_list_name = $('.new-list .js-new-list-name').val();
+ if(new_list_name.length === 0) {
+ notify('Ny epostliste', 'Navn på epostliste mangler', 'error');
+ return;
+ }
+ var text = $('.new-list textarea').val();
+ var emails = parseEmails(text);
+ if(emails.length === 0) {
+ notify('Ny epostliste', 'Ingen eposter i epost-feltet...', 'error');
+ return;
+ }
+ // Valid form
+ var prefix = $('.new-list .prefix-select .active').attr('data-value');
+ var source = prefix + new_list_name + "@" + email_domain.name;
+
+ var new_aliases = {};
+ new_aliases = _.map(emails, function(el) {
+ return {
+ 'source': source,
+ 'destination': el,
+ 'domain': email_domain.id
+ };
+ });
+ console.log(new_aliases);
+ $.ajax({
+ url: api_urls.aliases,
+ type: 'POST',
+ headers: {'X-CSRFToken': csrf_token},
+ dataType: 'json',
+ contentType: "application/json; charset=utf-8",
+ data: JSON.stringify(new_aliases),
+
+ }).done(function(resp) {
+ console.log(resp);
+ notify('Lagt til', 'Ny liste: ' + source + ' lagt til', 'success');
$('.new-list textarea').val('');
$('.new-list .js-new-list-name').val('');
- },
- 'json'
- );
- var added_list_html = nunjucks.render('list.html', { lists: new_list });
- forwards_container.prepend(added_list_html);
+ // FIXME: Existing list?
+ var added_list_html = nunjucks.render('list.html', { lists: new_aliases });
+ forwards_container.prepend(added_list_html);
+ });
- });
+ });
- /* Filter lists by orgunit */
- $(".orgunit-list a").on('click', function(e) {
- var prefix = $(this).attr('data-prefix');
- e.preventDefault();
+ /* Filter lists by orgunit */
+ $(".orgunit-list a").on('click', function(e) {
+ var prefix = $(this).attr('data-prefix');
+ e.preventDefault();
- /* Toggle selection */
- $(".orgunit-list li").removeClass('active');
- $(this).parent().toggleClass('active');
- $('.orgunits-select').val(prefix);
+ /* Toggle selection */
+ $(".orgunit-list li").removeClass('active');
+ $(this).parent().toggleClass('active');
+ $('.orgunits-select').val(prefix);
- filter_lists('^'+prefix+'-', true);
- $('.js-lists-filter-field').val('');
- });
- $(".orgunits-select").on('change', function() {
- var prefix = $(this).val();
+ filter_lists('^'+prefix+'-', true);
+ $('.js-lists-filter-field').val('');
+ });
+ $(".orgunits-select").on('change', function() {
+ var prefix = $(this).val();
- /* Toggle selection */
- $(".orgunit-list li").removeClass('active');
- $(".orgunit-list li a[data-prefix="+prefix+"]").parent().toggleClass('active');
+ /* Toggle selection */
+ $(".orgunit-list li").removeClass('active');
+ $(".orgunit-list li a[data-prefix="+prefix+"]").parent().toggleClass('active');
- filter_lists('^'+prefix+'-', true);
- $('.js-lists-filter-field').val('');
+ filter_lists('^'+prefix+'-', true);
+ $('.js-lists-filter-field').val('');
+ });
});
});
diff --git a/mailadmin/static/dist/scripts/templates.js b/mailadmin/static/dist/scripts/templates.js
index e29dc63..5625085 100644
--- a/mailadmin/static/dist/scripts/templates.js
+++ b/mailadmin/static/dist/scripts/templates.js
@@ -205,7 +205,9 @@ output += "-\n\t\t\t";
}
}
frame = frame.pop();
-output += "\n\t\t\t\n\t\t\n\t\t\n\t\t@studentersamfundet.no\n\t\n \tEposter
\n \n \n \n";
+output += "\n\t\t\t\n\t\t\n\t\t\n\t\t@";
+output += runtime.suppressValue(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "email_domain")),"name", env.autoesc), env.autoesc);
+output += "\n\t\n \tEposter
\n \n \n \n";
cb(null, output);
;
} catch (e) {
diff --git a/mailadmin/urls.py b/mailadmin/urls.py
index 29d40d8..74b0a2d 100644
--- a/mailadmin/urls.py
+++ b/mailadmin/urls.py
@@ -1,7 +1,7 @@
from django.conf.urls import patterns, url
from rest_framework.routers import DefaultRouter
-from mailadmin.views import MyUserViewSet, MyOrgUnitViewSet, OrgUnitViewSet, AliasesView
+from mailadmin.views import MyUserViewSet, MyOrgUnitViewSet, OrgUnitViewSet, AliasesView, get_domain
router = DefaultRouter()
router.register(r'me', MyUserViewSet, base_name='me')
@@ -12,4 +12,5 @@ urlpatterns = router.urls
urlpatterns += patterns(
'',
url(r'^aliases/$', AliasesView.as_view(), name='aliases'),
+ url(r'^emaildomain/$', get_domain, name='email-domain'),
)
diff --git a/mailadmin/views.py b/mailadmin/views.py
index 1d5dd80..4fa0137 100644
--- a/mailadmin/views.py
+++ b/mailadmin/views.py
@@ -1,3 +1,4 @@
+from django.conf import settings
from django.contrib.auth import login, logout as auth_logout
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import AuthenticationForm
@@ -6,6 +7,7 @@ from django.shortcuts import render, redirect
import logging
from requests import exceptions
from rest_framework import viewsets, views
+from rest_framework.decorators import api_view
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework import status
@@ -46,7 +48,7 @@ def logout(request):
class AliasesView(views.APIView):
- """ List, create and delete aliases from mxapi """
+ """ List, create and delete aliases from django-postfix-dovecot-api """
_api = DjangoPostfixDovecotAPI()
permission_classes = (SourcePrefixOwner,)
@@ -73,30 +75,32 @@ class AliasesView(views.APIView):
if len(my_prefixes) == 0:
return Response({'result': 'No results'}) # Need at least one
- try:
- res = self._api.list_aliases_regex(regexp)
- except exceptions.RequestException as e:
- logger.warning('mxapi errored {}'.format(e.strerror))
- return Response({'error': e.strerror}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
+ res = self._api.list_aliases_regex(regexp)
return Response(res)
def post(self, request):
- aliases = AliasSerializer(data=request.DATA, many=True)
+ aliases = AliasSerializer(data=request.data, many=True)
if not aliases.is_valid():
return Response(aliases.errors, status=status.HTTP_400_BAD_REQUEST)
res = self._api.create_aliases(aliases.data)
+
return Response(res)
def delete(self, request):
- aliases = AliasSerializer(data=request.DATA, many=True)
+ aliases = AliasSerializer(data=request.data, many=True)
if not aliases.is_valid():
return Response(aliases.errors, status=status.HTTP_400_BAD_REQUEST)
- # FIXME: not tested
- # res = self._api.delete_aliases(aliases)
- res = {'errors': 'Not implemented'}
+ try:
+ # FIXME: not tested
+ # res = self._api.delete_aliases(aliases)
+ res = {'errors': 'Not implemented'}
+ except exceptions.RequestException as e:
+ logger.warning('mxapi errored {}'.format(e.strerror))
+ return Response({'error': e.strerror}, status=status.HTTP_400_BAD_REQUEST)
+
return Response(res)
@@ -127,3 +131,14 @@ class OrgUnitViewSet(viewsets.ReadOnlyModelViewSet):
queryset = OrgUnit.objects.all()
serializer_class = OrgUnitSerializer
permission_classes = [IsAuthenticated]
+
+
+@api_view(['GET'])
+def get_domain(request):
+ api = DjangoPostfixDovecotAPI()
+ domains = api.list_domains(name=settings.NEUF_EMAIL_DOMAIN_NAME)
+
+ if len(domains) != 1:
+ return Response({'domain': domains})
+
+ return Response({'domain': domains[0]})
\ No newline at end of file