279 lines
11 KiB
Python
279 lines
11 KiB
Python
from django.shortcuts import redirect
|
|
from django.views.generic.edit import UpdateView, FormView
|
|
from django.views.generic.base import TemplateResponseMixin, View
|
|
from django.core.urlresolvers import reverse
|
|
from django.contrib import messages
|
|
from django.contrib.auth.models import User
|
|
from django.utils.translation import ugettext as _
|
|
from django.http import HttpResponseRedirect
|
|
|
|
|
|
import django_journal
|
|
|
|
|
|
from . import models
|
|
from . import forms
|
|
from . import cbv
|
|
from . import utils
|
|
|
|
|
|
class ProfileView(cbv.FormWithPrefixMixin, cbv.FormWithRequestMixin, cbv.FormWithPostTarget, UpdateView):
|
|
form_class = forms.ProfileForm
|
|
template_name = 'docbow/profile.html'
|
|
prefix = 'profile'
|
|
success_url = '#profile'
|
|
|
|
def get_object(self):
|
|
try:
|
|
return models.DocbowProfile.objects.get(user=self.request.user)
|
|
except models.DocbowProfile.DoesNotExist:
|
|
return None
|
|
|
|
def is_post_target(self):
|
|
return 'profile-clear_mobile_phone' in self.request.POST or \
|
|
'profile-validate' in self.request.POST
|
|
|
|
def post(self, request, *args, **kwargs):
|
|
self.object = self.get_object()
|
|
if 'profile-clear_mobile_phone' in self.request.POST:
|
|
if self.object:
|
|
self.object.mobile_phone = ''
|
|
self.object.save()
|
|
return redirect('profile')
|
|
return super(ProfileView, self).post(request, *args, **kwargs)
|
|
|
|
def form_valid(self, form):
|
|
self.request.record('update-profile', 'modified its profile',
|
|
**form.cleaned_data)
|
|
return super(ProfileView, self).form_valid(form)
|
|
|
|
|
|
class DelegateView(cbv.FormWithPrefixMixin, cbv.FormWithPostTarget, FormView):
|
|
form_class = forms.DelegationForm
|
|
template_name = 'docbow/delegate.html'
|
|
success_url = '#delegate'
|
|
prefix = 'delegate'
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(DelegateView, self).__init__(*args, **kwargs)
|
|
|
|
def add_journal_to_delegations(self, delegations):
|
|
delegations__to = [ delegation.to for delegation in delegations ]
|
|
journals = django_journal.Journal.objects \
|
|
.for_objects(delegations__to) \
|
|
.filter(tag__name='login') \
|
|
.order_by('-time')[:len(delegations__to)*5]
|
|
journal_by_users = dict()
|
|
for journal in journals:
|
|
for objectdata in journal.objectdata_set.all():
|
|
if objectdata.tag.name == 'delegate':
|
|
journal_by_users.setdefault(objectdata.object_id, []) \
|
|
.append(journal.time)
|
|
for delegation in delegations:
|
|
delegation.journals = journal_by_users.get(delegation.to.id, [])[:5]
|
|
|
|
@property
|
|
def delegations(self):
|
|
qs = models.Delegation.objects.all()
|
|
qs = qs.filter(by=self.request.user)
|
|
qs = qs.select_related()
|
|
qs = qs.prefetch_related('to__docbowprofile')
|
|
self.add_journal_to_delegations(qs)
|
|
return qs
|
|
|
|
def get_form_kwargs(self, **kwargs):
|
|
kwargs = super(DelegateView, self).get_form_kwargs(**kwargs)
|
|
kwargs['user'] = self.request.user
|
|
kwargs['delegatees'] = [ delegation.to for delegation in self.delegations ]
|
|
return kwargs
|
|
|
|
def delete(self, delegation):
|
|
request = self.request
|
|
delegation.delete()
|
|
delegate_user = delegation.to
|
|
request.record('delete-delegation', 'deleted delegation '
|
|
'{delegation} to user {delegated}',
|
|
delegation=delegation.id,
|
|
delegated=delegate_user)
|
|
user = request.user
|
|
# notify delegate
|
|
ctx = {
|
|
'user': utils.clean_ldap_user(user),
|
|
'delegate': delegate_user,
|
|
'to': [delegate_user.email],
|
|
'reply_to': user.email,
|
|
}
|
|
|
|
models.Notification.objects.create(kind='delete-delegation', ctx=ctx)
|
|
messages.info(request, _('Delegation %s supressed') %
|
|
delegate_user)
|
|
messages.info(request, _('%s has been notified.') %
|
|
delegate_user.email)
|
|
request.record('notify', 'notified {email} of '
|
|
'the deletion of its delegate user',
|
|
email=delegate_user.email)
|
|
|
|
# delete guest accounts
|
|
if delegation.guest_delegate:
|
|
delegate_user.delete()
|
|
request.record('delete-delegate', 'deleted delegate '
|
|
'user {username}, {first_name} {last_name}, '
|
|
'({email})',
|
|
username=delegate_user.username,
|
|
first_name=delegate_user.first_name,
|
|
last_name=delegate_user.last_name,
|
|
email=delegate_user.email)
|
|
return HttpResponseRedirect(self.success_url)
|
|
|
|
def is_post_target(self):
|
|
if 'delegate-create' in self.request.POST:
|
|
return True
|
|
for delegation in self.delegations:
|
|
username = delegation.to.username
|
|
if 'delegate-delete-{username}.x'.format(username=username) in \
|
|
self.request.POST:
|
|
return True
|
|
return False
|
|
|
|
def post(self, request, *args, **kwargs):
|
|
if 'delegate-create' in request.POST:
|
|
return super(DelegateView, self).post(request, *args, **kwargs)
|
|
for delegation in self.delegations:
|
|
username = delegation.to.username
|
|
if 'delegate-delete-{username}.x'.format(username=username) in \
|
|
self.request.POST:
|
|
return self.delete(delegation)
|
|
return self.get(request, *args, **kwargs)
|
|
|
|
def form_valid(self, form):
|
|
request = self.request
|
|
is_guest = not form.cleaned_data.get('existing_user')
|
|
ctx = {
|
|
'user': utils.clean_ldap_user(request.user),
|
|
'reply_to' :request.user.email,
|
|
'is_guest': is_guest,
|
|
}
|
|
if is_guest:
|
|
delegate_username = utils.get_free_delegation_number(request.user)
|
|
delegate_user = User(username=delegate_username,
|
|
first_name=form.cleaned_data.get('first_name', ''),
|
|
last_name=form.cleaned_data.get('last_name', ''),
|
|
email=form.cleaned_data.get('email', ''))
|
|
delegate_user.set_unusable_password()
|
|
delegate_user.save()
|
|
models.DocbowProfile.objects.create(user=delegate_user, is_guest=True)
|
|
delegation, created = models.Delegation.objects.get_or_create(by=request.user,
|
|
to=delegate_user)
|
|
request.record('create-delegate', 'created delegate with '
|
|
'parameters {first_name} {last_name} <{email}>',
|
|
**form.cleaned_data)
|
|
ctx.update({
|
|
'password_reset_link':
|
|
utils.make_password_reset_url(request, delegate_user),
|
|
'to': [form.cleaned_data['email']],
|
|
'delegate': delegate_user,
|
|
'delegation': delegation,
|
|
})
|
|
messages.info(request,
|
|
_('New delegation to user %s created.') % delegate_user.username)
|
|
messages.info(request,
|
|
_('A notification was sent to %s about this new delegation') % delegate_user.email)
|
|
else:
|
|
delegate_user = form.cleaned_data.get('existing_user')
|
|
delegate_username = delegate_user.username
|
|
delegation, created = models.Delegation.objects.get_or_create(by=request.user,
|
|
to=delegate_user)
|
|
ctx.update({
|
|
'to': models.all_emails(delegate_user),
|
|
'delegate': delegate_user,
|
|
'delegation': delegation,
|
|
})
|
|
messages.info(request,
|
|
_('New delegation to user %s created.') %
|
|
delegate_user.username)
|
|
messages.info(request,
|
|
_('A notification was sent to %s about this new delegation') % delegate_user.get_full_name())
|
|
models.Notification.objects.create(kind='new-delegation', ctx=ctx)
|
|
request.record('create-delegation', 'created delegation to '
|
|
'user {delegated}', delegated=delegate_user)
|
|
return super(DelegateView, self).form_valid(form)
|
|
|
|
|
|
def get_context_data(self, **kwargs):
|
|
ctx = super(DelegateView, self).get_context_data(**kwargs)
|
|
ctx['delegations'] = self.delegations
|
|
ctx['received_delegations'] = self.request.user.delegations_by.all()
|
|
return ctx
|
|
|
|
|
|
class PasswordChangeView(cbv.FormWithPrefixMixin, cbv.FormWithPostTarget, FormView):
|
|
template_name = 'registration/password_change_form.html'
|
|
form_class = forms.PasswordChangeFormWithLogging
|
|
prefix = 'password-change'
|
|
success_url = '#password-change'
|
|
|
|
def is_post_target(self):
|
|
return 'password-change-validate' in self.request.POST
|
|
|
|
def form_valid(self, form):
|
|
messages.info(self.request, _('Password changed'))
|
|
return super(PasswordChangeView, self).form_valid(form)
|
|
|
|
def get_form_kwargs(self, **kwargs):
|
|
kwargs = super(PasswordChangeView, self).get_form_kwargs(**kwargs)
|
|
kwargs['user'] = self.request.user
|
|
return kwargs
|
|
|
|
|
|
class FullProfileView(TemplateResponseMixin, View):
|
|
# multiplex all profile views
|
|
template_name = 'docbow/full-profile.html'
|
|
subviews = (
|
|
('profile_form', ProfileView),
|
|
('delegate_form', DelegateView),
|
|
('password_change_form', PasswordChangeView),
|
|
)
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
if models.is_guest(request.user):
|
|
self.subviews = filter(lambda s: s[0] != 'delegate_form', self.subviews)
|
|
print self.subviews
|
|
return super(FullProfileView, self).dispatch(request, *args, **kwargs)
|
|
|
|
def post(self, request, *args, **kwargs):
|
|
ctx = {}
|
|
for var_name, view_class in self.subviews:
|
|
res = self.get_view(var_name, view_class)
|
|
if isinstance(res, dict):
|
|
ctx.update(res)
|
|
else:
|
|
return res
|
|
return self.render_to_response(ctx)
|
|
|
|
def get_view(self, var_name, view_class):
|
|
view = view_class()
|
|
view.request, view.args, view.kwargs = \
|
|
self.request, self.args, self.kwargs
|
|
if hasattr(view, 'get_object'):
|
|
view.object = view.get_object()
|
|
if self.request.method == 'POST' and view.is_post_target():
|
|
res = view.post(self.request, *self.args, **self.kwargs)
|
|
if isinstance(res, HttpResponseRedirect):
|
|
return res
|
|
else:
|
|
ctx = res.context_data
|
|
ctx[var_name] = ctx.pop('form')
|
|
return ctx
|
|
else:
|
|
form_class = view.get_form_class()
|
|
form = view.get_form(form_class)
|
|
return view.get_context_data(**{var_name: form})
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
ctx = {}
|
|
for var_name, view_class in self.subviews:
|
|
ctx.update(self.get_view(var_name, view_class))
|
|
return self.render_to_response(ctx)
|
|
|
|
|