changeset 127:83e915192078

Implement user permissions setting view.
author Daniele Nicolodi <daniele@grinta.net>
date Fri, 14 Oct 2011 10:34:47 +0200
parents 18b94c01d497
children 1944c8ad80cb
files src/ltpdarepo/templates/users/permissions.html src/ltpdarepo/templates/users/view.html src/ltpdarepo/views/users.py
diffstat 3 files changed, 93 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ltpdarepo/templates/users/permissions.html	Fri Oct 14 10:34:47 2011 +0200
@@ -0,0 +1,32 @@
+{% import 'forms.html' as forms %}
+{% extends "layout.html" %}
+{% block title %}{{ user.username }}{% endblock %}
+{% block body %}
+<h2>Permissions for user &#x00AB;{{ user.username }}&#x00BB;</h2>
+<form action="" method="post">
+  <fieldset>
+    {% for field in form %}{{ forms.render_form_field(field) }}{% endfor %}
+    <table class="permissions">
+      <tr>
+        <th></th>
+        <th>select</th>
+        <th>insert</th>
+        <th>update</th>
+        <th>delete</th>
+      </tr>
+      {% for db, priv in permissions.iteritems() %}
+      <tr>
+        <td>
+          <a href="{{ url_for('manage.databases.view', database=db) }}">{{ db }}</a>
+        </td>
+        <td><input type="checkbox" name="{{db}}:select" value="Y" {%- if priv['select'] %} checked="checked" {% endif -%} /></td>
+        <td><input type="checkbox" name="{{db}}:insert" value="Y" {%- if priv['insert'] %} checked="checked" {% endif -%} /></td>
+        <td><input type="checkbox" name="{{db}}:update" value="Y" {%- if priv['update'] %} checked="checked" {% endif -%} /></td>
+        <td><input type="checkbox" name="{{db}}:delete" value="Y" {%- if priv['delete'] %} checked="checked" {% endif -%} /></td>
+      </tr>
+      {% endfor %}
+    </table>
+    <input id="submit" type="submit" name="submit" value="save" />
+  </fieldset>
+</form>
+{% endblock %}
--- a/src/ltpdarepo/templates/users/view.html	Fri Oct 14 10:34:47 2011 +0200
+++ b/src/ltpdarepo/templates/users/view.html	Fri Oct 14 10:34:47 2011 +0200
@@ -36,6 +36,7 @@
 <ul class="actions">
   <li><a href="{{ url_for('manage.users.edit', username=username) }}">Edit</a></li>
   <li><a href="{{ url_for('manage.users.drop', username=username) }}">Drop</a></li>
+  <li><a href="{{ url_for('manage.users.permissions', username=username) }}">Permissions</a></li>
   <li><a href="{{ url_for('manage.users.reset', username=username) }}">Reset password</a></li>
 </ul>
 {% endblock %}
--- a/src/ltpdarepo/views/users.py	Fri Oct 14 10:34:47 2011 +0200
+++ b/src/ltpdarepo/views/users.py	Fri Oct 14 10:34:47 2011 +0200
@@ -10,6 +10,11 @@
 from ltpdarepo.sign import Signer
 from ltpdarepo.mail import Mailer
 
+try:
+    from collections import OrderedDict
+except ImportError:
+    from ordereddict import OrderedDict
+
 app = Blueprint('manage.users', __name__)
 
 
@@ -124,6 +129,61 @@
     return render_template('users/reset.html', form=form, user=user)
 
 
+def _get_permissions(username):
+    curs = g.db.cursor()
+    curs.execute("""SELECT db_name,
+                      IFNULL(Select_priv, 'N'), IFNULL(Insert_priv, 'N'),
+                      IFNULL(Update_priv, 'N'), IFNULL(Delete_priv, 'N')
+                    FROM ltpda.available_dbs
+                    LEFT JOIN mysql.db ON db_name=Db AND User=%s
+                    ORDER BY db_name""", username)
+    privs = OrderedDict()
+    for row in curs.fetchall():
+        privs[row[0]] = {'select': row[1] == 'Y',
+                         'insert': row[2] == 'Y',
+                         'update': row[3] == 'Y',
+                         'delete': row[4] == 'Y'}
+    return privs
+
+
+def _permissions_updates(permissions, formdata):
+    updates = []
+    for db in permissions.keys():
+        for priv in ('select', 'insert', 'update', 'delete'):
+            value = bool(formdata.get('%s:%s' % (db, priv), False))
+            if permissions[db][priv] != value:
+                updates.append((db, priv, value))
+    return updates
+
+
+def _update_permissions(user, updates):
+    curs = g.db.cursor()
+    for database, priv, value in updates:
+        if value:
+            cmd = "GRANT %s ON `%s`.* TO %%s@%%s""" % (priv, database)
+        else:
+            cmd = "REVOKE %s ON `%s`.* FROM %%s@%%s""" % (priv, database)
+        curs.execute(cmd, (user, '%'))
+
+
+@app.route('/<username>/permissions', methods=('GET', 'POST'))
+@require('admin')
+def permissions(username):
+    user = User().load(username)
+    if user is None:
+        # not found
+        abort(404)
+    permissions = _get_permissions(username)
+    # use an empty form to have CSRF protection
+    form = Form()
+    if request.method == 'POST' and form.validate():
+        updates = _permissions_updates(permissions, request.form)
+        _update_permissions(username, updates)
+        flash('Permissions updated.')
+        return redirect(url_for('manage.users.view', username=username))
+    return render_template('users/permissions.html', user=user, permissions=permissions, form=form)
+
+
 @app.route('/<username>/drop', methods=('GET', 'POST'))
 @require('admin')
 def drop(username):