diff --git a/htdocs/checkcolumn.js b/htdocs/checkcolumn.js new file mode 100644 index 0000000..54c39f2 --- /dev/null +++ b/htdocs/checkcolumn.js @@ -0,0 +1,39 @@ +/* + * Ext JS Library 2.2 + * Copyright(c) 2006-2008, Ext JS, LLC. + * licensing@extjs.com + * + * http://extjs.com/license + */ + +Ext.grid.CheckColumn = function(config){ + Ext.apply(this, config); + if(!this.id){ + this.id = Ext.id(); + } + this.renderer = this.renderer.createDelegate(this); +}; + +Ext.grid.CheckColumn.prototype ={ + init : function(grid){ + this.grid = grid; + this.grid.on('render', function(){ + var view = this.grid.getView(); + view.mainBody.on('mousedown', this.onMouseDown, this); + }, this); + }, + + onMouseDown : function(e, t){ + if(t.className && t.className.indexOf('x-grid3-cc-'+this.id) != -1){ + e.stopEvent(); + var index = this.grid.getView().findRowIndex(t); + var record = this.grid.store.getAt(index); + record.set(this.dataIndex, !record.data[this.dataIndex]); + } + }, + + renderer : function(v, p, record){ + p.css += ' x-grid3-check-col-td'; + return '
 
'; + } +}; diff --git a/pyweb/mumble/urls.py b/pyweb/mumble/urls.py index 3ca550e..431deb4 100644 --- a/pyweb/mumble/urls.py +++ b/pyweb/mumble/urls.py @@ -18,6 +18,7 @@ from django.conf.urls.defaults import * urlpatterns = patterns( 'mumble.views', + ( r'(?P\d+)/users', 'users' ), ( r'(?P\d+)/(?P\d+)texture.png', 'showTexture' ), ( r'(?P\d+)/texture.png', 'showTexture' ), ( r'(?P\d+)', 'show' ), diff --git a/pyweb/mumble/views.py b/pyweb/mumble/views.py index 27091b5..326f769 100644 --- a/pyweb/mumble/views.py +++ b/pyweb/mumble/views.py @@ -14,6 +14,7 @@ * GNU General Public License for more details. """ +import simplejson from StringIO import StringIO from django.shortcuts import render_to_response, get_object_or_404, get_list_or_404 @@ -21,6 +22,7 @@ from django.template import RequestContext from django.http import Http404, HttpResponse, HttpResponseRedirect from django.core.urlresolvers import reverse from django.contrib.auth.decorators import login_required +from django.contrib.auth.models import User from django.conf import settings from models import Mumble, MumbleUser @@ -174,4 +176,62 @@ def showTexture( request, server, userid = None ): return HttpResponse( buffer.getvalue(), "image/png" ); +@login_required +def users( request, server ): + srv = get_object_or_404( Mumble, id=int(server) ); + + if not srv.isUserAdmin( request.user ): + return HttpResponse( + simplejson.dumps({ 'success': False, 'objects': [], 'errormsg': 'Access denied' }), + mimetype='text/javascript' + ); + + if request.method == 'POST': + data = simplejson.loads( request.POST['data'] ); + print "Json: ", data; + for record in data: + if record['id'] == -1: + if record['delete']: + continue; + mu = MumbleUser( server=srv ); + else: + mu = MumbleUser.objects.get( id=record['id'] ); + if record['delete']: + mu.delete(); + continue; + + mu.name = record['name']; + mu.password = record['password']; + mu.isAdmin = record['admin']; + + if record['owner_id']: + mu.owner = User.objects.get( id=int(record['owner_id']) ); + + mu.save(); + + users = []; + for mu in srv.mumbleuser_set.all(): + owner = None; + owner_id = None; + if mu.owner is not None: + owner = unicode( mu.owner ); + owner_id = mu.owner.id + + users.append( { + 'id': mu.id, + 'name': mu.name, + 'password': None, + 'owner': owner, + 'owner_id': owner_id, + 'admin': mu.getAdmin(), + } ); + + return HttpResponse( + simplejson.dumps( { 'success': True, 'objects': users } ), + mimetype='text/javascript' + ); + + + + diff --git a/template/index.htm b/template/index.htm index 5271b38..5f82dcd 100644 --- a/template/index.htm +++ b/template/index.htm @@ -11,6 +11,7 @@ + {% block HeadTag %} {% endblock %} diff --git a/template/mumble/mumble.htm b/template/mumble/mumble.htm index 02a47f6..f5927ee 100644 --- a/template/mumble/mumble.htm +++ b/template/mumble/mumble.htm @@ -144,6 +144,37 @@ Ext.get( 'mumble_admin' ).addClass( 'x-hide-display' ); {% endif %} + {% if CurrentUserIsAdmin %} + userRecord = Ext.data.Record.create([ + { name: 'id', type: 'int' }, + { name: 'name', type: 'string' }, + { name: 'password', type: 'string' }, + { name: 'owner', type: 'string' }, + { name: 'owner_id', type: 'int' }, + { name: 'admin', type: 'bool' }, + { name: 'delete', type: 'bool' }, + ]); + + userAdminStore = new Ext.data.Store({ + url: '/mumble/{{ DBaseObject.id }}/users/', + reader: new Ext.data.JsonReader({ + root: 'objects', + fields: userRecord, + }), + autoLoad: true, + }); + + adminColumn = new Ext.grid.CheckColumn({ + header: '{% trans "Admin on root channel" %}', + dataIndex: 'admin', + }); + + deleteColumn = new Ext.grid.CheckColumn({ + header: '{% trans "Delete" %}', + dataIndex: 'delete', + }); + {% endif %} + var cardpanel = new Ext.Panel({ renderTo: 'mumble_ext_container', layout: 'card', @@ -157,13 +188,79 @@ defaults: { autoheight: true }, activeTab: {{ DisplayTab }}, items: [ - { contentEl: 'mumble_motd', title: '{% trans "Server Info" %}', autoScroll: true }, - { contentEl: 'mumble_registration', title: '{% trans "Registration" %}', autoScroll: true }, + { contentEl: 'mumble_motd', title: '{% trans "Server Info" %}', autoScroll: true }, + { contentEl: 'mumble_registration', title: '{% trans "Registration" %}', autoScroll: true }, {% if CurrentUserIsAdmin %} - { contentEl: 'mumble_admin', title: '{% trans "Administration" %}', autoScroll: true }, + { contentEl: 'mumble_admin', title: '{% trans "Administration" %}', autoScroll: true }, {% endif %} {% if Registered %} - { contentEl: 'mumble_texture', title: '{% trans "User Texture" %}', autoScroll: true }, + { contentEl: 'mumble_texture',title: '{% trans "User Texture" %}', autoScroll: true }, + {% endif %} + {% if CurrentUserIsAdmin %} + { + title: '{% trans "User List" %}', + xtype: 'editorgrid', + store: userAdminStore, + cm: new Ext.grid.ColumnModel( [ { + header: '{% trans "name" %}', + dataIndex: 'name', + editor: new Ext.form.TextField({ + allowBlank: false, + }), + }, { + header: '{% trans "Account owner" %}', + dataIndex: 'owner', + editor: new Ext.form.TextField(), + }, adminColumn, { + header: '{% trans "Change password" %}', + dataIndex: 'password', + editor: new Ext.form.TextField({ + inputType: 'password', + }), + }, deleteColumn ] ), + tbar: [{ + text: '{% trans "Add" %}', + handler : function(){ + userAdminStore.add( new userRecord( { + id: -1, + name: 'New User', + admin: false, + owner: null, + owner_id: null, + password: null, + 'delete': false, + } ) ); + } + }, { + text: '{% trans "Save" %}', + handler : function(){ + data = []; + for( i = 0; i < userAdminStore.data.items.length; i++ ){ + rec = userAdminStore.data.items[i]; + if( rec.dirty ){ + data.push(rec.data); + } + } + + var conn = new Ext.data.Connection(); + conn.request( { + url: userAdminStore.url, + params: { data: Ext.encode( data ), }, + success: function(){ + for( i = 0; i < userAdminStore.data.items.length; i++ ){ + rec = userAdminStore.data.items[i]; + if( rec.data['delete'] == true ) + userAdminStore.remove( rec ); + else if( rec.dirty ){ + rec.commit(); + } + } + }, + } ); + } + }], + plugins: [ adminColumn, deleteColumn ], + }, {% endif %} ] },