mixins.py 3.51 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# coding: utf8
# nm.debian.org view mixins
#
# Copyright (C) 2014  Enrico Zini <enrico@debian.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

from __future__ import print_function
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from django.views.generic import TemplateView
24
from django.core.exceptions import PermissionDenied
25
26
27
28
from . import models as bmodels

class VisitorMixin(object):
    """
Enrico Zini's avatar
Enrico Zini committed
29
30
    Add self.visitor and self.impersonator to the View for the person visiting
    the site
31
    """
Enrico Zini's avatar
Enrico Zini committed
32
    # Define to "dd" "am" or "admin" to raise PermissionDenied if the
33
34
35
    # given test on the visitor fails
    require_visitor = None

Enrico Zini's avatar
Enrico Zini committed
36
    def set_visitor_info(self):
37
38
        self.impersonator = None

Enrico Zini's avatar
Enrico Zini committed
39
        if not self.request.user.is_authenticated():
40
41
            self.visitor = None
        else:
Enrico Zini's avatar
Enrico Zini committed
42
            self.visitor = self.request.user
43
44
45

            # Implement impersonation if requested in session
            if self.visitor.is_admin:
Enrico Zini's avatar
Enrico Zini committed
46
                key = self.request.session.get("impersonate", None)
47
48
49
50
51
                if key is not None:
                    p = bmodels.Person.lookup(key)
                    if p is not None:
                        self.impersonator = self.visitor
                        self.visitor = p
52

Enrico Zini's avatar
Enrico Zini committed
53
54
55
    def pre_dispatch(self):
        self.set_visitor_info()

56
57
        if self.require_visitor and (self.visitor is None or self.require_visitor not in self.visitor.perms):
            raise PermissionDenied
58

Enrico Zini's avatar
Enrico Zini committed
59
60
    def dispatch(self, request, *args, **kwargs):
        self.pre_dispatch()
61
        return super(VisitorMixin, self).dispatch(request, *args, **kwargs)
62
63
64

    def get_context_data(self, **kw):
        ctx = super(VisitorMixin, self).get_context_data(**kw)
65
66
        ctx["visitor"] = self.visitor
        ctx["impersonator"] = self.impersonator
67
68
69
70
71
        return ctx

class VisitorTemplateView(VisitorMixin, TemplateView):
    pass

Enrico Zini's avatar
Enrico Zini committed
72
73
74
75
76
class VisitPersonMixin(VisitorMixin):
    """
    Visit a person record. Adds self.person and self.vperms with the
    permissions the visitor has over the person
    """
77
78
79
80
    # Define to "edit_bio" "edit_ldap" or "view_person_audit_log" to raise
    # PermissionDenied if the given test on the person-visitor fails
    require_vperms = None

Enrico Zini's avatar
Enrico Zini committed
81
82
83
84
85
86
87
88
89
    def pre_dispatch(self):
        super(VisitPersonMixin, self).pre_dispatch()
        key = self.kwargs.get("key", None)
        if key is None:
            self.person = self.visitor
        else:
            self.person = bmodels.Person.lookup_or_404(key)
        self.vperms = self.person.permissions_of(self.visitor)

90
91
92
        if self.require_vperms and self.require_vperms not in self.vperms.perms:
            raise PermissionDenied

Enrico Zini's avatar
Enrico Zini committed
93
94
95
96
97
98
99
100
    def get_context_data(self, **kw):
        ctx = super(VisitPersonMixin, self).get_context_data(**kw)
        ctx["person"] = self.person
        ctx["vperms"] = self.vperms
        return ctx

class VisitPersonTemplateView(VisitPersonMixin, TemplateView):
    pass