Skip to content

Instantly share code, notes, and snippets.

@drscream
Created September 9, 2014 13:48
Show Gist options
  • Save drscream/e54f4f12f338f72fe3f8 to your computer and use it in GitHub Desktop.
Save drscream/e54f4f12f338f72fe3f8 to your computer and use it in GitHub Desktop.
from django import forms
from django.utils.translation import ugettext_lazy as _
from django.db import connections, transaction
def dbname(username):
return 'db_' + username
class DatabaseCreateForm(forms.Form):
name = forms.RegexField(max_length=16, regex=r'^[a-z0-9_]+$', label = _("Name"))
password = forms.CharField(widget=forms.widgets.PasswordInput, label = _("Password"))
def clean(self):
cleaned_data = super(DatabaseCreateForm, self).clean()
name = cleaned_data.get("name")
database = dbname(name)
cursor = connections['kumquat_mysql'].cursor()
cursor.execute('SHOW DATABASES LIKE %s', [database])
if cursor.rowcount > 0:
raise forms.ValidationError("Databse name already in use")
cursor.execute('SELECT user FROM mysql.user WHERE user = %s', [name])
if cursor.rowcount > 0:
raise forms.ValidationError("Username already in use")
return cleaned_data
def create_database(self):
name = self.cleaned_data.get("name")
password = self.cleaned_data.get("password")
database = dbname(name)
c = connections['kumquat_mysql'].cursor()
with transaction.atomic(using='kumquat_mysql'):
# we can concat the database name with the query because only safe characters are allowed by the regex field
c.execute('CREATE DATABASE ' + database)
# clear possible previous permissions
c.execute("GRANT USAGE ON *.* TO %s", [name])
c.execute("DROP USER %s", [name])
c.execute("GRANT ALL ON " + database + ".* TO %s@localhost IDENTIFIED BY %s", [name, password])
c.execute("GRANT ALL ON " + database + ".* TO %s@'%%' IDENTIFIED BY %s", [name, password])
class DatabaseUpdateForm(forms.Form):
new_password = forms.CharField(widget=forms.widgets.PasswordInput, label = _("Password"))
def update_database(self, name):
password = self.cleaned_data.get("new_password")
c = connections['kumquat_mysql'].cursor()
c.execute("set password for %s@'%%' = PASSWORD(%s)", (name, password))
c.execute("set password for %s@'localhost' = PASSWORD(%s)", (name, password))
from django.core.urlresolvers import reverse_lazy
from django.views.generic import ListView
from django.views.generic.edit import FormView
from django.core.exceptions import PermissionDenied
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from django.utils.translation import ugettext as _
from django.contrib.messages.views import SuccessMessageMixin
from django.db import connections
from django.http import Http404
from kumquat.utils import LoginRequiredMixin
from forms import *
def list_databases(*kwargs):
cursor = connections['kumquat_mysql'].cursor()
cursor.execute("SHOW DATABASES LIKE 'db_%'")
dbs = []
for db in cursor.fetchall():
database = db[0]
name = database[3:]
dbs += [{
"name": name,
"database": database,
}]
return dbs
class DatabaseList(LoginRequiredMixin, ListView):
template_name = 'mysql/database_list.html'
get_queryset = list_databases
class DatabaseCreate(LoginRequiredMixin, SuccessMessageMixin, FormView):
template_name = 'mysql/database_form.html'
success_url = reverse_lazy('mysql_database_list')
success_message = _("%(name)s was created successfully")
form_class = DatabaseCreateForm
def form_valid(self, form):
form.create_database()
return super(DatabaseCreate, self).form_valid(form)
@login_required
def databaseUpdate(request, slug):
dbs = [db["name"] for db in list_databases()]
if(slug not in dbs):
raise Http404
form = DatabaseUpdateForm(request.POST or None)
if form.is_valid():
form.update_database(slug)
return redirect('mysql_database_list')
return render(request, 'mysql/database_password.html', {'form': form})
@login_required
def databaseDelete(request, slug):
dbs = [db["name"] for db in list_databases()]
if(slug not in dbs):
raise Http404
if request.method != "POST":
raise PermissionDenied
database = dbname(slug)
c = connections['kumquat_mysql'].cursor()
c.execute("drop user " + slug + "@'%'")
c.execute("drop user " + slug + "@localhost")
c.execute("drop database " + database)
return redirect('mysql_database_list')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment