# -*- coding: utf-8 -*- # Copyright (C) 1998-2013 by the Free Software Foundation, Inc. # # This file is part of Postorius. # # Postorius is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) # any later version. # # Postorius is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # more details. # # You should have received a copy of the GNU General Public License along with # Postorius. If not, see <http://www.gnu.org/licenses/>. import re import sys import json import logging from django.conf import settings from django.contrib import messages from django.contrib.auth import logout, authenticate, login from django.contrib.auth.decorators import (login_required, permission_required, user_passes_test) from django.contrib.auth.forms import (AuthenticationForm, PasswordResetForm, SetPasswordForm, PasswordChangeForm) from django.contrib.auth.models import User from django.core.urlresolvers import reverse from django.http import HttpResponse, HttpResponseRedirect from django.shortcuts import render_to_response, redirect from django.template import Context, loader, RequestContext from django.utils.decorators import method_decorator from django.utils.translation import gettext as _ from urllib2 import HTTPError from mailmanclient import Client from postorius import utils from postorius.models import (Domain, List, Member, MailmanUser, MailmanApiError, Mailman404Error) from postorius.forms import * from postorius.auth.decorators import * from postorius.views.generic import MailingListView, MailmanUserView logger = logging.getLogger(__name__) @login_required def user_settings(request, tab="membership", template='postorius/user_settings.html', fqdn_listname=None): """ Change the user or the membership settings. The user must be logged in to be allowed to change any settings. TODO: * add CSS to display tabs ?? * add missing functionality in REST server and client and change to the correct calls here """ member = request.user.username message = '' form = None the_list = None membership_lists = [] try: c = Client('%s/3.0' % settings.REST_SERVER, settings.API_USER, settings.API_PASS) if tab == "membership": if fqdn_listname: the_list = List.objects.get(fqdn_listname=fqdn_listname) user_object = the_list.get_member(member) else: message = ("") for mlist in List.objects.all(): try: mlist.get_member(member) membership_lists.append(mlist) except: pass else: # address_choices for the 'address' field must be a list of # tuples of length 2 raise Exception("") address_choices = [[addr, addr] for addr in user_object.address] except AttributeError, e: return render_to_response( 'postorius/errors/generic.html', {'error': str(e) + "REST API not found / Offline"}, context_instance=RequestContext(request)) except ValueError, e: return render_to_response('postorius/errors/generic.html', {'error': e}, context_instance=RequestContext(request)) except HTTPError, e: return render_to_response( 'postorius/errors/generic.html', {'error': _("List ") + fqdn_listname + _(" does not exist")}, context_instance=RequestContext(request)) #----------------------------------------------------------------- if request.method == 'POST': # The form enables both user and member settings. As a result # we must find out which was the case. raise Exception("Please fix bug prior submitting the form") if tab == "membership": form = MembershipSettings(request.POST) if form.is_valid(): member_object = c.get_member(member, request.GET["list"]) member_object.update(request.POST) message = "The membership settings have been updated." else: # the post request came from the user tab # the 'address' field need choices as a tuple of length 2 addr_choices = [[request.POST["address"], request.POST["address"]]] form = UserSettings(addr_choices, request.POST) if form.is_valid(): user_object.update(request.POST) # to get the full list of addresses we need to # reinstantiate the form with all the addresses # TODO: should return the correct settings from the DB, # not just the address_choices (add mock data to _User # class and make the call with 'user_object.info') form = UserSettings(address_choices) message = "The user settings have been updated." else: if tab == "membership" and fqdn_listname: if fqdn_listname: # TODO : fix LP:821069 in mailman.client the_list = List.objects.get(fqdn_listname=fqdn_listname) member_object = the_list.get_member(member) # TODO: add delivery_mode and deliver_status from a # list of tuples at one point, currently we hard code # them in forms.py # instantiate the form with the correct member info """ acknowledge_posts hide_address receive_list_copy receive_own_postings delivery_mode delivery_status """ data = {} form = MembershipSettings(data) elif tab == "user": # TODO: should return the correct settings from the DB, # not just the address_choices (add mock data to _User # class and make the call with 'user_object._info') The 'language' # field must also be added as a list of tuples with correct # values (is currently hard coded in forms.py). data = {} # Todo https://bugs.launchpad.net/mailman/+bug/821438 form = UserSettings(data) return render_to_response(template, {'form': form, 'tab': tab, 'list': the_list, 'membership_lists': membership_lists, 'message': message, 'member': member}, context_instance=RequestContext(request)) class UserSummaryView(MailmanUserView): """Shows a summary of a user. """ @method_decorator(user_passes_test(lambda u: u.is_superuser)) def get(self, request, user_id): settingsform = MembershipSettings() memberships = self._get_memberships() return render_to_response('postorius/users/summary.html', {'mm_user': self.mm_user, 'settingsform': settingsform, 'memberships': memberships}, context_instance=RequestContext(request)) class UserSubscriptionsView(MailmanUserView): """Shows the subscriptions of a user. """ def get(self, request): memberships = self._get_memberships() return render_to_response('postorius/user_subscriptions.html', {'memberships': memberships}, context_instance=RequestContext(request)) @user_passes_test(lambda u: u.is_superuser) def user_index(request, template='postorius/users/index.html'): """Show a table of all users. """ error = None try: mm_users = MailmanUser.objects.all() except MailmanApiError: return utils.render_api_error(request) return render_to_response(template, {'error': error, 'mm_users': mm_users}, context_instance=RequestContext(request)) @user_passes_test(lambda u: u.is_superuser) def user_new(request): message = None if request.method == 'POST': form = UserNew(request.POST) if form.is_valid(): user = MailmanUser(display_name=form.cleaned_data['display_name'], email=form.cleaned_data['email'], password=form.cleaned_data['password']) try: user.save() except MailmanApiError: return utils.render_api_error(request) except HTTPError, e: messages.error(request, e) else: messages.success(request, _("New User registered")) return redirect("user_index") else: form = UserNew() return render_to_response('postorius/users/new.html', {'form': form, 'message': message}, context_instance=RequestContext(request)) def user_logout(request): logout(request) return redirect('user_login') def user_login(request, template='postorius/login.html'): if request.method == 'POST': form = AuthenticationForm(request.POST) user = authenticate(username=request.POST.get('username'), password=request.POST.get('password')) if user is not None: logger.debug(user) if user.is_active: login(request, user) return redirect(request.GET.get('next', 'list_index')) else: form = AuthenticationForm() return render_to_response(template, {'form': form}, context_instance=RequestContext(request)) @login_required() def user_profile(request, user_email=None): if not request.user.is_authenticated(): return redirect('user_login') #try: # the_user = User.objects.get(email=user_email) #except MailmanApiError: # return utils.render_api_error(request) return render_to_response('postorius/user_profile.html', # {'mm_user': the_user}, context_instance=RequestContext(request)) @login_required def user_tasks(request): return render_to_response('postorius/user_tasks.html', context_instance=RequestContext(request)) @login_required def more_info_tab(request, formid=None, helpid=None, template='postorius/more_info_display.html'): """Displays more_info in new tab. """ if(formid == 'list_settings'): form = ListSettings(visible_section='List Identity', visible_option='None', data=request.POST) for field in form: if field.name == helpid: help_text = field.help_text return render_to_response(template, {'help_text':help_text, 'helpid':helpid}, context_instance=RequestContext(request))