user.py 8.68 KB
Newer Older
Skia's avatar
Skia committed
1 2
# This file contains all the views that concern the user model
from django.shortcuts import render, redirect, get_object_or_404
Skia's avatar
Skia committed
3
from django.contrib.auth import logout as auth_logout, views
4
from django.core.urlresolvers import reverse
5
from django.core.exceptions import PermissionDenied, ObjectDoesNotExist
Skia's avatar
Skia committed
6
from django.http import Http404
Skia's avatar
Skia committed
7
from django.views.generic.edit import UpdateView
8
from django.views.generic import ListView, DetailView, TemplateView
9 10
from django.forms.models import modelform_factory
from django.forms import CheckboxSelectMultiple
Skia's avatar
Skia committed
11
from django.template.response import TemplateResponse
Skia's avatar
Skia committed
12
from django.conf import settings
13 14

from datetime import timedelta
Skia's avatar
Skia committed
15 16
import logging

Skia's avatar
Skia committed
17
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin
18
from core.views.forms import RegisteringForm, UserPropForm, UserProfileForm
Skia's avatar
Skia committed
19
from core.models import User
Skia's avatar
Skia committed
20

Skia's avatar
Skia committed
21 22 23 24 25 26
def login(request):
    """
    The login view

    Needs to be improve with correct handling of form exceptions
    """
Skia's avatar
Skia committed
27
    return views.login(request, template_name="core/login.jinja")
Skia's avatar
Skia committed
28 29 30 31 32 33 34 35 36 37 38

def logout(request):
    """
    The logout view
    """
    return views.logout_then_login(request)

def password_change(request):
    """
    Allows a user to change its password
    """
Skia's avatar
Skia committed
39
    return views.password_change(request, template_name="core/password_change.jinja", post_change_redirect=reverse("core:password_change_done"))
Skia's avatar
Skia committed
40 41 42 43 44

def password_change_done(request):
    """
    Allows a user to change its password
    """
Skia's avatar
Skia committed
45
    return views.password_change_done(request, template_name="core/password_change_done.jinja")
Skia's avatar
Skia committed
46

Skia's avatar
Skia committed
47 48 49 50
def password_root_change(request, user_id):
    """
    Allows a root user to change someone's password
    """
Skia's avatar
Skia committed
51
    if not request.user.is_root:
Skia's avatar
Skia committed
52 53 54 55 56 57 58 59 60 61 62 63 64
        raise PermissionDenied
    user = User.objects.filter(id=user_id).first()
    if not user:
        raise Http404("User not found")
    if request.method == "POST":
        form = views.SetPasswordForm(user=user, data=request.POST)
        if form.is_valid():
            form.save()
            return redirect("core:password_change_done")
    else:
        form = views.SetPasswordForm(user=user)
    return TemplateResponse(request, "core/password_change.jinja", {'form': form, 'target': user})

Skia's avatar
Skia committed
65
def password_reset(request):
Skia's avatar
Skia committed
66 67 68
    """
    Allows someone to enter an email adresse for resetting password
    """
Skia's avatar
Skia committed
69
    return views.password_reset(request,
Skia's avatar
Skia committed
70 71
                                template_name="core/password_reset.jinja",
                                email_template_name="core/password_reset_email.jinja",
Skia's avatar
Skia committed
72
                                post_reset_redirect="core:password_reset_done",
Skia's avatar
Skia committed
73
                               )
Skia's avatar
Skia committed
74 75

def password_reset_done(request):
Skia's avatar
Skia committed
76 77 78
    """
    Confirm that the reset email has been sent
    """
Skia's avatar
Skia committed
79
    return views.password_reset_done(request, template_name="core/password_reset_done.jinja")
Skia's avatar
Skia committed
80

Skia's avatar
Skia committed
81
def password_reset_confirm(request, uidb64=None, token=None):
Skia's avatar
Skia committed
82 83 84
    """
    Provide a reset password formular
    """
Skia's avatar
Skia committed
85 86
    return views.password_reset_confirm(request, uidb64=uidb64, token=token,
                                        post_reset_redirect="core:password_reset_complete",
Skia's avatar
Skia committed
87
                                        template_name="core/password_reset_confirm.jinja",
Skia's avatar
Skia committed
88 89 90
                                       )

def password_reset_complete(request):
Skia's avatar
Skia committed
91 92 93
    """
    Confirm the password has sucessfully been reset
    """
Skia's avatar
Skia committed
94
    return views.password_reset_complete(request,
Skia's avatar
Skia committed
95
                                         template_name="core/password_reset_complete.jinja",
Skia's avatar
Skia committed
96
                                        )
Skia's avatar
Skia committed
97

Skia's avatar
Skia committed
98

Skia's avatar
Skia committed
99
def register(request):
Skia's avatar
Skia committed
100
    context = {}
Skia's avatar
Skia committed
101 102 103 104 105 106 107 108 109 110 111 112 113 114
    if request.method == 'POST':
        form = RegisteringForm(request.POST)
        if form.is_valid():
            logging.debug("Registering "+form.cleaned_data['first_name']+form.cleaned_data['last_name'])
            u = form.save()
            context['user_registered'] = u
            context['tests'] = 'TEST_REGISTER_USER_FORM_OK'
            form = RegisteringForm()
        else:
            context['error'] = 'Erreur'
            context['tests'] = 'TEST_REGISTER_USER_FORM_FAIL'
    else:
        form = RegisteringForm()
    context['form'] = form.as_p()
Skia's avatar
Skia committed
115
    return render(request, "core/register.jinja", context)
Skia's avatar
Skia committed
116

Skia's avatar
Skia committed
117
class UserView(CanViewMixin, DetailView):
Skia's avatar
Skia committed
118 119 120
    """
    Display a user's profile
    """
Skia's avatar
Skia committed
121 122 123
    model = User
    pk_url_kwarg = "user_id"
    context_object_name = "profile"
Skia's avatar
Skia committed
124
    template_name = "core/user_detail.jinja"
Skia's avatar
Skia committed
125

126 127 128 129 130 131 132 133 134 135 136
class UserStatsView(CanViewMixin, DetailView):
    """
    Display a user's stats
    """
    model = User
    pk_url_kwarg = "user_id"
    context_object_name = "profile"
    template_name = "core/user_stats.jinja"

    def get_context_data(self, **kwargs):
        kwargs = super(UserStatsView, self).get_context_data(**kwargs)
Skia's avatar
Skia committed
137 138 139 140 141 142 143 144
        from counter.models import Counter
        foyer = Counter.objects.filter(name="Foyer").first()
        mde = Counter.objects.filter(name="MDE").first()
        gommette = Counter.objects.filter(name="La Gommette").first()
        kwargs['total_perm_time'] = sum([p.end-p.start for p in self.object.permanencies.all()], timedelta())
        kwargs['total_foyer_time'] = sum([p.end-p.start for p in self.object.permanencies.filter(counter=foyer)], timedelta())
        kwargs['total_mde_time'] = sum([p.end-p.start for p in self.object.permanencies.filter(counter=mde)], timedelta())
        kwargs['total_gommette_time'] = sum([p.end-p.start for p in self.object.permanencies.filter(counter=gommette)], timedelta())
145 146
        return kwargs

Skia's avatar
Skia committed
147 148 149 150 151 152 153 154 155
class UserMiniView(CanViewMixin, DetailView):
    """
    Display a user's profile
    """
    model = User
    pk_url_kwarg = "user_id"
    context_object_name = "profile"
    template_name = "core/user_mini.jinja"

Skia's avatar
Skia committed
156 157 158 159 160
class UserListView(ListView):
    """
    Displays the user list
    """
    model = User
Skia's avatar
Skia committed
161
    template_name = "core/user_list.jinja"
Skia's avatar
Skia committed
162

Skia's avatar
Skia committed
163
class UserUpdateProfileView(CanEditMixin, UpdateView):
Skia's avatar
Skia committed
164 165 166 167 168
    """
    Edit a user's profile
    """
    model = User
    pk_url_kwarg = "user_id"
Skia's avatar
Skia committed
169
    template_name = "core/user_edit.jinja"
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
    form_class = UserProfileForm

    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        self.form = self.get_form()
        if self.form.instance.profile_pict and not request.user.is_in_group(settings.SITH_MAIN_BOARD_GROUP):
            self.form.fields.pop('profile_pict', None)
        return self.render_to_response(self.get_context_data(form=self.form))

    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        self.form = self.get_form()
        if self.form.instance.profile_pict and not request.user.is_in_group(settings.SITH_MAIN_BOARD_GROUP):
            self.form.fields.pop('profile_pict', None)
        files = request.FILES.items()
        self.form.process(files)
        if request.user.is_authenticated() and request.user.can_edit(self.object) and self.form.is_valid():
            return super(UserUpdateProfileView, self).form_valid(self.form)
        return self.form_invalid(self.form)

    def get_context_data(self, **kwargs):
        kwargs = super(UserUpdateProfileView, self).get_context_data(**kwargs)
        kwargs['profile'] = self.form.instance
        kwargs['form'] = self.form
        return kwargs
Skia's avatar
Skia committed
195

196
class UserUpdateGroupView(CanEditPropMixin, UpdateView):
Skia's avatar
Skia committed
197 198 199 200 201
    """
    Edit a user's groups
    """
    model = User
    pk_url_kwarg = "user_id"
202 203 204
    template_name = "core/user_group.jinja"
    form_class = modelform_factory(User, fields=['groups'],
            widgets={'groups':CheckboxSelectMultiple})
Skia's avatar
Skia committed
205
    context_object_name = "profile"
Skia's avatar
Skia committed
206

207 208 209 210
class UserToolsView(TemplateView):
    """
    Displays the logged user's tools
    """
Skia's avatar
Skia committed
211
    template_name = "core/user_tools.jinja"
Skia's avatar
Skia committed
212

213 214 215 216 217 218
    def get_context_data(self, **kwargs):
        from launderette.models import Launderette
        kwargs = super(UserToolsView, self).get_context_data(**kwargs)
        kwargs['launderettes'] = Launderette.objects.all()
        return kwargs

Skia's avatar
Skia committed
219 220 221 222 223 224 225 226 227 228 229 230
class UserAccountView(DetailView):
    """
    Display a user's account
    """
    model = User
    pk_url_kwarg = "user_id"
    template_name = "core/user_account.jinja"

    def dispatch(self, request, *arg, **kwargs): # Manually validates the rights
        res = super(UserAccountView, self).dispatch(request, *arg, **kwargs)
        if (self.object == request.user
                or request.user.is_in_group(settings.SITH_GROUPS['accounting-admin']['name'])
Skia's avatar
Skia committed
231
                or request.user.is_root):
Skia's avatar
Skia committed
232 233 234 235 236 237 238 239 240 241 242 243 244 245
            return res
        raise PermissionDenied

    def get_context_data(self, **kwargs):
        kwargs = super(UserAccountView, self).get_context_data(**kwargs)
        kwargs['profile'] = self.object
        try:
            kwargs['customer'] = self.object.customer
        except:
            pass
        # TODO: add list of month where account has activity
        return kwargs