diff --git a/pyweb/mumble/mmobjects.py b/pyweb/mumble/mmobjects.py index eca2cab..3d0424c 100644 --- a/pyweb/mumble/mmobjects.py +++ b/pyweb/mumble/mmobjects.py @@ -152,14 +152,14 @@ class mmChannel( object ): doc="True if this channel is the server's default channel." ) - def asDict( self ): + def asDict( self, authed=False ): chandata = self.channel_obj.__dict__.copy() - chandata['users'] = [ pl.asDict() for pl in self.players ] - chandata['channels'] = [ sc.asDict() for sc in self.subchans ] + chandata['users'] = [ pl.asDict( authed ) for pl in self.players ] + chandata['channels'] = [ sc.asDict( authed ) for sc in self.subchans ] chandata['x-connecturl'] = self.connecturl return chandata - def asXml( self, parentnode ): + def asXml( self, parentnode, authed=False ): from xml.etree.cElementTree import SubElement me = SubElement( parentnode, "channel" ) for key in self.channel_obj.__dict__: @@ -176,9 +176,9 @@ class mmChannel( object ): me.set( "x-connecturl", self.connecturl ) for sc in self.subchans: - sc.asXml(me) + sc.asXml(me, authed) for pl in self.players: - pl.asXml(me) + pl.asXml(me, authed) def asMvXml( self, parentnode ): """ Return an XML tree for this channel suitable for MumbleViewer-ng. """ @@ -284,17 +284,20 @@ class mmPlayer( object ): """ Call callback on myself. """ callback( self, lvl ) - def asDict( self ): + def asDict( self, authed=False ): pldata = self.player_obj.__dict__.copy() - pldata["x-addrstring"] = self.ipaddress - if self.mumbleuser: - if self.mumbleuser.hasTexture(): - pldata['x-texture'] = self.mumbleuser.textureUrl + if authed: + pldata["x-addrstring"] = self.ipaddress + else: + del pldata["address"] + + if self.mumbleuser and self.mumbleuser.hasTexture(): + pldata['x-texture'] = self.mumbleuser.textureUrl return pldata - def asXml( self, parentnode ): + def asXml( self, parentnode, authed=False ): from xml.etree.cElementTree import SubElement me = SubElement( parentnode, "user" ) for key in self.player_obj.__dict__: @@ -308,10 +311,12 @@ class mmPlayer( object ): else: me.set( key, unicode(val) ) - me.set( "x-addrstring", self.ipaddress ) + if authed: + me.set( "x-addrstring", self.ipaddress ) + else: + me.set( "address", "" ) - if self.mumbleuser: - if self.mumbleuser.hasTexture(): + if self.mumbleuser and self.mumbleuser.hasTexture(): me.set( 'x-texture', self.mumbleuser.textureUrl ) def asMvXml( self, parentnode ): diff --git a/pyweb/mumble/models.py b/pyweb/mumble/models.py index d611638..a419ae2 100644 --- a/pyweb/mumble/models.py +++ b/pyweb/mumble/models.py @@ -548,18 +548,18 @@ class Mumble( models.Model ): version = property( lambda self: self.server.version, doc="The version of Murmur." ) prettyversion = property( lambda self: self.server.prettyversion ) - def asDict( self ): + def asDict( self, authed=False ): return { 'name': self.name, 'id': self.id, - 'root': self.rootchan.asDict(), + 'root': self.rootchan.asDict( authed ), 'x-connecturl': self.connecturl } - def asXml( self ): + def asXml( self, authed=False ): from xml.etree.cElementTree import Element root = Element( "server", id=unicode(self.id), name=self.name ) root.set( 'x-connecturl', self.connecturl ) - self.rootchan.asXml(root) + self.rootchan.asXml( root, authed ) return root def asMvXml( self ): diff --git a/pyweb/mumble/views.py b/pyweb/mumble/views.py index 79bac31..94e5d97 100644 --- a/pyweb/mumble/views.py +++ b/pyweb/mumble/views.py @@ -378,6 +378,24 @@ def mmng_tree( request, server ): ) +def cvp_checkauth( request, srv ): + """ Check if the user is allowed to see private fields. """ + # http://www.djangosnippets.org/snippets/243/ + if srv.isUserAdmin( request.user ): + return True + if 'HTTP_AUTHORIZATION' in request.META: + auth = request.META['HTTP_AUTHORIZATION'].split() + if len(auth) == 2: + # NOTE: We only support basic authentication for now. + if auth[0].lower() == "basic": + import base64 + from django.contrib.auth import authenticate + uname, passwd = base64.b64decode(auth[1]).split(':') + user = authenticate(username=uname, password=passwd) + if user is not None and user.is_active and srv.isUserAdmin( user ): + return True + return False + def cvp_json( request, server ): """ JSON reference implementation for the Channel Viewer Protocol. @@ -391,7 +409,7 @@ def cvp_json( request, server ): prefix = "" return HttpResponse( - prefix + "(" + simplejson.dumps( srv.asDict() ) + ")", + prefix + "(" + simplejson.dumps( srv.asDict( cvp_checkauth( request, srv ) ) ) + ")", mimetype='text/javascript' ) @@ -404,7 +422,7 @@ def cvp_xml( request, server ): srv = get_object_or_404( Mumble, id=int(server) ) return HttpResponse( ''+\ - xml_to_string( srv.asXml(), encoding='utf-8' ), + xml_to_string( srv.asXml( cvp_checkauth( request, srv ) ), encoding='utf-8' ), mimetype='text/xml' )