views.py 7.19 KB
Newer Older
1
# -*- coding: utf-8 -*-
Pierre-Elliott Bécue's avatar
Pierre-Elliott Bécue committed
2 3
# Application pour permettre aux adhérents de lister leur page perso
# Gabriel Détraz <detraz@crans.org>, Hamza Dely <dely@crans.org>
4

5
from django.shortcuts import render, redirect
6
from django.contrib.auth.decorators import login_required
7
from django.views.decorators.http import require_http_methods
Daniel STAN's avatar
Daniel STAN committed
8
from django.core.exceptions import PermissionDenied
9
from models import PagePerso
Mathilde Espinasse's avatar
Mathilde Espinasse committed
10
from django.utils.translation import ugettext_lazy as _
Daniel STAN's avatar
Daniel STAN committed
11 12

from intranet import conn_pool
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
from gestion.mysql import make_cursor
from gestion import secrets_new as secrets

try:
    cursor = make_cursor("intranet_cursor", secrets.get("intranet_mysql_admin"))
except (secrets.SecretNotFound, secrets.SecretForbidden):
    cursor = None

# intranet_mysql_admin
from forms import PagePersoForm, SqlPasswordForm

def test_backticks(name):
    if '`' in name:
        raise ValueError("%r should not contain '`'")
    return name
28

Daniel STAN's avatar
Daniel STAN committed
29 30 31 32 33 34 35 36 37 38 39 40
def managed_logins(user):
    """Renvoie la liste des logins gérés par ``user``. Travaille avec un générateur
    pour ne pas vraiment calculer la liste des clubs, si non nécessaire."""
    yield user.username
    luser = conn_pool.get_user(user)
    if not user:
        return
    for club in luser.clubs():
        for uid in club.get('uid', []):
            yield uid.value

def get_login(request, login):
41 42
    """Renvoie le login présumé de la page perso. Et vérifie que l'utilisateur
    courant a bien le droit de faire des modifs dessus"""
Daniel STAN's avatar
Daniel STAN committed
43
    login = login or request.user.username
44 45 46
    if login in managed_logins(request.user) or request.user.has_perm('crans_nounou'):
        return login
    raise PermissionDenied
47
    
48 49
# Vue d'affichage du formulaire d'indexation de la pageperso
@login_required
50
@require_http_methods(["GET", "POST"])
Daniel STAN's avatar
Daniel STAN committed
51 52
def pageperso(request, login=None):
    login = get_login(request, login)
53
    result = PagePerso.objects.filter(login=login)
54 55
    if request.method == "POST":
        if result.exists():
Pierre-Elliott Bécue's avatar
Pierre-Elliott Bécue committed
56
            form = PagePersoForm(request.POST, instance=result[0])
57 58 59
        else:
            form = PagePersoForm(request.POST)
        if form.is_valid():
Pierre-Elliott Bécue's avatar
Pierre-Elliott Bécue committed
60 61 62 63
            if result.exists():
                form.save()
            else:
                new_page = form.save(commit=False)
64
                new_page.login = login
Pierre-Elliott Bécue's avatar
Pierre-Elliott Bécue committed
65
                new_page.save()
Mathilde Espinasse's avatar
Mathilde Espinasse committed
66
            labelperso = _(u"Modifier l'affichage de ma page perso")
Pierre-Elliott Bécue's avatar
Pierre-Elliott Bécue committed
67
            deref = True
68
        else:
Mathilde Espinasse's avatar
Mathilde Espinasse committed
69
            labelperso = _(u"Référencer ma page perso")
Pierre-Elliott Bécue's avatar
Pierre-Elliott Bécue committed
70
            deref = False
71

Pierre-Elliott Bécue's avatar
Pierre-Elliott Bécue committed
72
    # Si c'est pas un post, on renvoie le formulaire prérempli (si deja une page)
73
    elif request.method == "GET":
74 75 76
        if result.exists():
            res = result[0]
            initial_data = {
Pierre-Elliott Bécue's avatar
Pierre-Elliott Bécue committed
77 78
                'nom_site': res.nom_site,
                'slogan': res.slogan,
79
            }
Pierre-Elliott Bécue's avatar
Pierre-Elliott Bécue committed
80
            form = PagePersoForm(instance=result[0])
Mathilde Espinasse's avatar
Mathilde Espinasse committed
81
            labelperso = _(u"Modifier l'affichage de ma page perso")
Pierre-Elliott Bécue's avatar
Pierre-Elliott Bécue committed
82
            deref = True
83 84
        # Si la page existe pas, le champ est vierge
        else:
Pierre-Elliott Bécue's avatar
Pierre-Elliott Bécue committed
85
            form = PagePersoForm()
Mathilde Espinasse's avatar
Mathilde Espinasse committed
86
            labelperso = _(u"Référencer ma page perso")
Pierre-Elliott Bécue's avatar
Pierre-Elliott Bécue committed
87
            deref = False
88 89 90 91 92
        if cursor:
            mysql_error = False
            with cursor() as cur:
                if cur.execute(
                    "SELECT User From mysql.user WHERE User = %s",
93
                    (login, )
94 95 96 97 98 99 100 101 102
                ):
                    # one user found, clean cursor
                    cur.fetchone()
                    mysql_exists = True
                    if not cur.execute(
                        (
                            "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA "
                            "WHERE SCHEMA_NAME = %s"
                        ),
103
                        (login, )
104 105 106 107
                    ):
                        cur.execute(
                            (
                                "CREATE DATABASE `%s` CHARACTER SET utf8 COLLATE utf8_unicode_ci;"
108
                            ) % test_backticks(login)
109 110 111 112
                        )
                        cur.execute(
                            (
                                "GRANT ALL PRIVILEGES ON `%s`.* TO %%s@'localhost'"
113 114
                            ) % test_backticks(login),
                            (login, )
115 116 117
                        )
        else:
            mysql_error = True
Daniel STAN's avatar
Daniel STAN committed
118 119 120 121
    logins = managed_logins(request.user)
    return render(request, "pageperso/affichage.html",
        locals()
    )
122

123
@login_required
Daniel STAN's avatar
Daniel STAN committed
124 125
def deref(request, login=None):
    login = get_login(request, login)
126
    result = PagePerso.objects.filter(login=login)
127
    result.delete()
Daniel STAN's avatar
Daniel STAN committed
128
    return redirect("pageperso:pageperso", login=login)
129 130 131 132


@login_required
@require_http_methods(["GET", "POST"])
Daniel STAN's avatar
Daniel STAN committed
133 134
def create_database(request, login=None):
    login = get_login(request, login)
135
    if cursor is None:
Daniel STAN's avatar
Daniel STAN committed
136
        return redirect("pageperso:pageperso", login=login)
137 138 139 140 141 142 143 144
    if request.method == "POST":
        form = SqlPasswordForm(request.POST)
        if form.is_valid():
            with cursor() as cur:
                cur.execute(
                    (
                        "CREATE DATABASE IF NOT EXISTS `%s` CHARACTER SET utf8 "
                        "COLLATE utf8_unicode_ci;"
145
                    ) % test_backticks(login)
146 147 148 149
                )
                cur.execute(
                    (
                        "GRANT ALL PRIVILEGES ON `%s`.* TO %%s@'localhost' IDENTIFIED BY %%s"
150 151
                    ) % test_backticks(login),
                    (login, form.cleaned_data["password"])
152
                )
Daniel STAN's avatar
Daniel STAN committed
153
            return redirect("pageperso:pageperso", login=login)
154 155
    elif request.method == "GET":
        form = SqlPasswordForm()
Daniel STAN's avatar
Daniel STAN committed
156
    return render(request, "pageperso/createdb.html", {'form': form, 'login': login, })
157 158 159 160


@login_required
@require_http_methods(["GET", "POST"])
Daniel STAN's avatar
Daniel STAN committed
161 162
def reset_db_password(request, login=None):
    login = get_login(request, login)
163
    if cursor is None:
Daniel STAN's avatar
Daniel STAN committed
164
        return redirect("pageperso:pageperso", login=login)
165 166 167 168 169 170
    if request.method == "POST":
        form = SqlPasswordForm(request.POST)
        if form.is_valid():
            with cursor() as cur:
                if cur.execute(
                    "SELECT User From mysql.user WHERE User = %s",
171
                    (login, )
172 173 174 175
                ):
                    cur.fetchone()
                    cur.execute(
                        "SET PASSWORD FOR %s@'localhost' = PASSWORD(%s);",
176
                        (login, form.cleaned_data["password"],)
177
                    )
Daniel STAN's avatar
Daniel STAN committed
178
            return redirect("pageperso:pageperso", login=login)
179 180
    elif request.method == "GET":
        form = SqlPasswordForm()
Daniel STAN's avatar
Daniel STAN committed
181
    return render(request, "pageperso/createdb.html", {'form': form, 'login': login})
182 183 184 185


@login_required
@require_http_methods(["GET", "POST"])
Daniel STAN's avatar
Daniel STAN committed
186 187
def delete_database(request, login=None):
    login = get_login(request, login)
188
    if cursor is None:
Daniel STAN's avatar
Daniel STAN committed
189
        return redirect("pageperso:pageperso", login=login)
190 191 192
    if request.method == "POST":
        if request.POST.get("confirm") == "yes":
            with cursor() as cur:
193 194
                cur.execute("DROP DATABASE IF EXISTS `%s`" % test_backticks(login))
                cur.execute("DROP USER %s@'localhost'", (login, ))
Daniel STAN's avatar
Daniel STAN committed
195 196
        return redirect("pageperso:pageperso", login=login)
    return render(request, "pageperso/deletedb.html", {'login': login})