views.py 7.98 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2017  Gabriel Détraz
# Copyright © 2017  Goulven Kermarec
# Copyright © 2017  Augustin Lemesle
#
# This program 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 2 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
chirac's avatar
chirac committed
22 23 24 25
"""
Fonctions de la page d'accueil et diverses fonctions utiles pour tous
les views
"""
26

27 28
from __future__ import unicode_literals

29 30 31 32
from itertools import chain
import git
from reversion.models import Version

33
from django.http import Http404
LEVY-FALK Hugo's avatar
LEVY-FALK Hugo committed
34
from django.urls import reverse
35
from django.shortcuts import render, redirect
36
from django.template.context_processors import csrf
37
from django.contrib.auth.decorators import login_required
38
from django.contrib import messages
39
from django.conf import settings
40
from django.utils.translation import ugettext as _
41 42
from django.views.decorators.cache import cache_page

Maël Kervella's avatar
Maël Kervella committed
43
import preferences
44 45 46 47
from preferences.models import (
    Service,
    GeneralOption,
    AssoOption,
Gabriel Detraz's avatar
Gabriel Detraz committed
48
    HomeOption
49
)
50
import users
Maël Kervella's avatar
Maël Kervella committed
51 52 53
import cotisations
import topologie
import machines
54

55
from .utils import re2o_paginator
56
from .contributors import CONTRIBUTORS
chirac's avatar
chirac committed
57

Maël Kervella's avatar
Maël Kervella committed
58

chirac's avatar
chirac committed
59
def form(ctx, template, request):
chirac's avatar
chirac committed
60
    """Form générique, raccourci importé par les fonctions views du site"""
chirac's avatar
chirac committed
61 62 63
    context = ctx
    context.update(csrf(request))
    return render(request, template, context)
chirac's avatar
chirac committed
64 65 66


def index(request):
chirac's avatar
chirac committed
67
    """Affiche la liste des services sur la page d'accueil de re2o"""
68 69 70
    services = [[], [], []]
    for indice, serv in enumerate(Service.objects.all()):
        services[indice % 3].append(serv)
Gabriel Detraz's avatar
Gabriel Detraz committed
71 72 73
    twitter_url = HomeOption.get_cached_value('twitter_url')
    facebook_url = HomeOption.get_cached_value('facebook_url')
    twitter_account_name = HomeOption.get_cached_value('twitter_account_name')
74 75 76 77 78 79 80 81
    asso_name = AssoOption.get_cached_value('pseudo')
    return form({
         'services_urls': services,
         'twitter_url': twitter_url,
         'twitter_account_name' : twitter_account_name,
         'facebook_url': facebook_url,
         'asso_name': asso_name
         }, 're2o/index.html', request)
82

Maël Kervella's avatar
Maël Kervella committed
83

84
#: Binding the corresponding char sequence of history url to re2o models.
85
HISTORY_BIND = {
Maël Kervella's avatar
Maël Kervella committed
86 87 88 89 90 91 92 93
    'users': {
        'user': users.models.User,
        'ban': users.models.Ban,
        'whitelist': users.models.Whitelist,
        'school': users.models.School,
        'listright': users.models.ListRight,
        'serviceuser': users.models.ServiceUser,
        'listshell': users.models.ListShell,
94
    },
Maël Kervella's avatar
Maël Kervella committed
95 96
    'preferences': {
        'service': preferences.models.Service,
97
    },
Maël Kervella's avatar
Maël Kervella committed
98 99 100 101 102
    'cotisations': {
        'facture': cotisations.models.Facture,
        'article': cotisations.models.Article,
        'paiement': cotisations.models.Paiement,
        'banque': cotisations.models.Banque,
103
    },
Maël Kervella's avatar
Maël Kervella committed
104 105 106 107 108 109 110 111 112 113
    'topologie': {
        'switch': topologie.models.Switch,
        'port': topologie.models.Port,
        'room': topologie.models.Room,
        'stack': topologie.models.Stack,
        'modelswitch': topologie.models.ModelSwitch,
        'constructorswitch': topologie.models.ConstructorSwitch,
        'accesspoint': topologie.models.AccessPoint,
        'switchbay': topologie.models.SwitchBay,
        'building': topologie.models.Building,
114
    },
Maël Kervella's avatar
Maël Kervella committed
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
    'machines': {
        'machine': machines.models.Machine,
        'interface': machines.models.Interface,
        'domain': machines.models.Domain,
        'machinetype': machines.models.MachineType,
        'iptype': machines.models.IpType,
        'extension': machines.models.Extension,
        'soa': machines.models.SOA,
        'mx': machines.models.Mx,
        'txt': machines.models.Txt,
        'srv': machines.models.Srv,
        'ns': machines.models.Ns,
        'service': machines.models.Service,
        'vlan': machines.models.Vlan,
        'nas': machines.models.Nas,
        'ipv6list': machines.models.Ipv6List,
131
    },
132 133
}

Maël Kervella's avatar
Maël Kervella committed
134

135
@login_required
136
def history(request, application, object_name, object_id):
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
    """Render history for a model.

    The model is determined using the `HISTORY_BIND` dictionnary if none is
    found, raises a Http404. The view checks if the user is allowed to see the
    history using the `can_view` method of the model.

    Args:
        request: The request sent by the user.
        object_name: Name of the model.
        object_id: Id of the object you want to acces history.

    Returns:
        The rendered page of history if access is granted, else the user is
        redirected to their profile page, with an error message.

    Raises:
        Http404: This kind of models doesn't have history.
    """
155
    try:
156
        model = HISTORY_BIND[application][object_name]
157
    except KeyError:
158
        raise Http404(u"Il n'existe pas d'historique pour ce modèle.")
159 160
    object_name_id = object_name + 'id'
    kwargs = {object_name_id: object_id}
161
    try:
162
        instance = model.get_instance(**kwargs)
163 164
    except model.DoesNotExist:
        messages.error(request, u"Entrée inexistante")
Maël Kervella's avatar
Maël Kervella committed
165 166 167
        return redirect(reverse(
            'users:profil',
            kwargs={'userid': str(request.user.id)}
168 169 170 171 172 173
        ))
    can, msg = instance.can_view(request.user)
    if not can:
        messages.error(request, msg or "Vous ne pouvez pas accéder à ce menu")
        return redirect(reverse(
            'users:profil',
Maël Kervella's avatar
Maël Kervella committed
174
            kwargs={'userid': str(request.user.id)}
175
        ))
176
    pagination_number = GeneralOption.get_cached_value('pagination_number')
177
    reversions = Version.objects.get_for_object(instance)
178 179
    if hasattr(instance, 'linked_objects'):
        for related_object in chain(instance.linked_objects()):
Maël Kervella's avatar
Maël Kervella committed
180 181
            reversions = (reversions |
                          Version.objects.get_for_object(related_object))
182
    reversions = re2o_paginator(request, reversions, pagination_number)
183 184 185 186 187 188
    return render(
        request,
        're2o/history.html',
        {'reversions': reversions, 'object': instance}
    )

189

190
@cache_page(7 * 24 * 60 * 60)
191
def about_page(request):
192 193 194
    """ The view for the about page.
    Fetch some info about the configuration of the project. If it can't
    get the info from the Git repository, fallback to default string """
195
    option = AssoOption.objects.get()
196 197
    git_info_contributors = CONTRIBUTORS
    try:
198
        git_repo = git.Repo(settings.BASE_DIR)
199 200 201 202 203 204 205
        git_info_remote = ", ".join(git_repo.remote().urls)
        git_info_branch = git_repo.active_branch.name
        last_commit = git_repo.commit()
        git_info_commit = last_commit.hexsha
        git_info_commit_date = last_commit.committed_datetime
    except:
        NO_GIT_MSG = _("Unable to get the information")
206 207 208 209 210
        git_info_remote = NO_GIT_MSG
        git_info_branch = NO_GIT_MSG
        git_info_commit = NO_GIT_MSG
        git_info_commit_date = NO_GIT_MSG

211
    dependencies = settings.INSTALLED_APPS + settings.MIDDLEWARE_CLASSES
212

213 214 215
    return render(
        request,
        "re2o/about.html",
216
        {
Maël Kervella's avatar
Maël Kervella committed
217 218
            'description': option.description,
            'AssoName': option.name,
219 220 221 222 223 224 225
            'git_info_contributors': git_info_contributors,
            'git_info_remote': git_info_remote,
            'git_info_branch': git_info_branch,
            'git_info_commit': git_info_commit,
            'git_info_commit_date': git_info_commit_date,
            'dependencies': dependencies
        }
226
    )
227 228 229 230 231


def handler500(request):
    """The handler view for a 500 error"""
    return render(request, 'errors/500.html')