Browse Source

add a set of unit tests that check the form authentication mechanisms

Natenom/support-murmur-13-1446181288462
Michael Ziegler 14 years ago
parent
commit
4d40eae52b
  1. 441
      pyweb/mumble/fixtures/testdb.json
  2. 387
      pyweb/mumble/tests.py

441
pyweb/mumble/fixtures/testdb.json

@ -0,0 +1,441 @@
[
{
"pk": 1,
"model": "mumble.mumbleserver",
"fields": {
"dbus": "Meta:tcp -h 127.0.0.1 -p 6502",
"secret": ""
}
},
{
"pk": 1,
"model": "mumble.mumble",
"fields": {
"addr": "0.0.0.0 ::",
"name": "test server",
"display": "",
"server": 1,
"port": null,
"srvid": 1
}
},
{
"pk": 2,
"model": "mumble.mumble",
"fields": {
"addr": "",
"name": "n00 test serv0r",
"display": "",
"server": 1,
"port": null,
"srvid": 2
}
},
{
"pk": 1,
"model": "mumble.mumbleuser",
"fields": {
"owner": 1,
"mumbleid": 1,
"password": "",
"name": "svedrin",
"server": 1
}
},
{
"pk": 13,
"model": "auth.permission",
"fields": {
"codename": "add_logentry",
"name": "Can add log entry",
"content_type": 5
}
},
{
"pk": 14,
"model": "auth.permission",
"fields": {
"codename": "change_logentry",
"name": "Can change log entry",
"content_type": 5
}
},
{
"pk": 15,
"model": "auth.permission",
"fields": {
"codename": "delete_logentry",
"name": "Can delete log entry",
"content_type": 5
}
},
{
"pk": 4,
"model": "auth.permission",
"fields": {
"codename": "add_group",
"name": "Can add group",
"content_type": 2
}
},
{
"pk": 5,
"model": "auth.permission",
"fields": {
"codename": "change_group",
"name": "Can change group",
"content_type": 2
}
},
{
"pk": 6,
"model": "auth.permission",
"fields": {
"codename": "delete_group",
"name": "Can delete group",
"content_type": 2
}
},
{
"pk": 10,
"model": "auth.permission",
"fields": {
"codename": "add_message",
"name": "Can add message",
"content_type": 4
}
},
{
"pk": 11,
"model": "auth.permission",
"fields": {
"codename": "change_message",
"name": "Can change message",
"content_type": 4
}
},
{
"pk": 12,
"model": "auth.permission",
"fields": {
"codename": "delete_message",
"name": "Can delete message",
"content_type": 4
}
},
{
"pk": 1,
"model": "auth.permission",
"fields": {
"codename": "add_permission",
"name": "Can add permission",
"content_type": 1
}
},
{
"pk": 2,
"model": "auth.permission",
"fields": {
"codename": "change_permission",
"name": "Can change permission",
"content_type": 1
}
},
{
"pk": 3,
"model": "auth.permission",
"fields": {
"codename": "delete_permission",
"name": "Can delete permission",
"content_type": 1
}
},
{
"pk": 7,
"model": "auth.permission",
"fields": {
"codename": "add_user",
"name": "Can add user",
"content_type": 3
}
},
{
"pk": 8,
"model": "auth.permission",
"fields": {
"codename": "change_user",
"name": "Can change user",
"content_type": 3
}
},
{
"pk": 9,
"model": "auth.permission",
"fields": {
"codename": "delete_user",
"name": "Can delete user",
"content_type": 3
}
},
{
"pk": 16,
"model": "auth.permission",
"fields": {
"codename": "add_contenttype",
"name": "Can add content type",
"content_type": 6
}
},
{
"pk": 17,
"model": "auth.permission",
"fields": {
"codename": "change_contenttype",
"name": "Can change content type",
"content_type": 6
}
},
{
"pk": 18,
"model": "auth.permission",
"fields": {
"codename": "delete_contenttype",
"name": "Can delete content type",
"content_type": 6
}
},
{
"pk": 40,
"model": "auth.permission",
"fields": {
"codename": "add_evolution",
"name": "Can add evolution",
"content_type": 14
}
},
{
"pk": 41,
"model": "auth.permission",
"fields": {
"codename": "change_evolution",
"name": "Can change evolution",
"content_type": 14
}
},
{
"pk": 42,
"model": "auth.permission",
"fields": {
"codename": "delete_evolution",
"name": "Can delete evolution",
"content_type": 14
}
},
{
"pk": 37,
"model": "auth.permission",
"fields": {
"codename": "add_version",
"name": "Can add version",
"content_type": 13
}
},
{
"pk": 38,
"model": "auth.permission",
"fields": {
"codename": "change_version",
"name": "Can change version",
"content_type": 13
}
},
{
"pk": 39,
"model": "auth.permission",
"fields": {
"codename": "delete_version",
"name": "Can delete version",
"content_type": 13
}
},
{
"pk": 31,
"model": "auth.permission",
"fields": {
"codename": "add_mumble",
"name": "Can add Server instance",
"content_type": 11
}
},
{
"pk": 32,
"model": "auth.permission",
"fields": {
"codename": "change_mumble",
"name": "Can change Server instance",
"content_type": 11
}
},
{
"pk": 33,
"model": "auth.permission",
"fields": {
"codename": "delete_mumble",
"name": "Can delete Server instance",
"content_type": 11
}
},
{
"pk": 28,
"model": "auth.permission",
"fields": {
"codename": "add_mumbleserver",
"name": "Can add Mumble Server",
"content_type": 10
}
},
{
"pk": 29,
"model": "auth.permission",
"fields": {
"codename": "change_mumbleserver",
"name": "Can change Mumble Server",
"content_type": 10
}
},
{
"pk": 30,
"model": "auth.permission",
"fields": {
"codename": "delete_mumbleserver",
"name": "Can delete Mumble Server",
"content_type": 10
}
},
{
"pk": 34,
"model": "auth.permission",
"fields": {
"codename": "add_mumbleuser",
"name": "Can add User account",
"content_type": 12
}
},
{
"pk": 35,
"model": "auth.permission",
"fields": {
"codename": "change_mumbleuser",
"name": "Can change User account",
"content_type": 12
}
},
{
"pk": 36,
"model": "auth.permission",
"fields": {
"codename": "delete_mumbleuser",
"name": "Can delete User account",
"content_type": 12
}
},
{
"pk": 25,
"model": "auth.permission",
"fields": {
"codename": "add_registrationprofile",
"name": "Can add registration profile",
"content_type": 9
}
},
{
"pk": 26,
"model": "auth.permission",
"fields": {
"codename": "change_registrationprofile",
"name": "Can change registration profile",
"content_type": 9
}
},
{
"pk": 27,
"model": "auth.permission",
"fields": {
"codename": "delete_registrationprofile",
"name": "Can delete registration profile",
"content_type": 9
}
},
{
"pk": 19,
"model": "auth.permission",
"fields": {
"codename": "add_session",
"name": "Can add session",
"content_type": 7
}
},
{
"pk": 20,
"model": "auth.permission",
"fields": {
"codename": "change_session",
"name": "Can change session",
"content_type": 7
}
},
{
"pk": 21,
"model": "auth.permission",
"fields": {
"codename": "delete_session",
"name": "Can delete session",
"content_type": 7
}
},
{
"pk": 22,
"model": "auth.permission",
"fields": {
"codename": "add_site",
"name": "Can add site",
"content_type": 8
}
},
{
"pk": 23,
"model": "auth.permission",
"fields": {
"codename": "change_site",
"name": "Can change site",
"content_type": 8
}
},
{
"pk": 24,
"model": "auth.permission",
"fields": {
"codename": "delete_site",
"name": "Can delete site",
"content_type": 8
}
},
{
"pk": 1,
"model": "auth.user",
"fields": {
"username": "svedrin",
"first_name": "",
"last_name": "",
"is_active": true,
"is_superuser": true,
"is_staff": true,
"last_login": "2010-08-02 15:56:15",
"groups": [],
"user_permissions": [],
"password": "sha1$71bab$1dd52b90d6b63ba95483292dc50ac58ee71ca551",
"email": "diese-addy@funzt-halt.net",
"date_joined": "2010-07-23 08:43:57"
}
}
]

387
pyweb/mumble/tests.py

@ -15,195 +15,212 @@
* GNU General Public License for more details.
"""
import simplejson
from django.conf import settings
from django.test import TestCase
from models import Mumble
from utils import ObjectInfo
class InstancesHandling( TestCase ):
""" Tests creation, editing and removing of vserver instances. """
from django.test.client import Client
from django.contrib.auth.models import User
from models import Mumble, MumbleUser
from utils import ObjectInfo
class ExtDirectFormTestMixin(object):
""" Methods for testing a Form exported via Ext.Direct.
These only define the methods, you will need to inherit your TestCase
from this class and set the following class attributes:
api_baseurl:
The URL under which the Ext.Direct provider has been registered.
formname:
The name of the exported form class.
"""
def setUp(self):
self.cl = Client()
super(ExtDirectFormTestMixin, self).setUp()
self.tid = 1
def testFormApi(self):
rawr = self.cl.get( "%s/%s.js" % ( self.api_baseurl, self.formname.lower() ) )
self.assertEquals( rawr.status_code, 200 )
def formGet( self, data=[] ):
rawr = self.cl.post( self.api_baseurl+'/router',
data=simplejson.dumps({
'tid': self.tid,
'action': ('XD_%s' % self.formname),
'method': 'get',
'data': data,
'type': 'rpc'
}),
content_type='application/json' )
self.tid += 1
response = simplejson.loads(rawr.content)
if response['type'] == "exception":
raise Exception( response["message"] )
self.assert_( "result" in response )
return response['result']
def formPost( self, data={} ):
postdata={
'extAction': ('XD_%s' % self.formname),
'extMethod': 'update',
'extTID': self.tid,
'extType': 'rpc',
'extUpload': 'false',
}
self.tid += 1
postdata.update( data )
rawr = self.cl.post( self.api_baseurl+'/router', data=postdata )
response = simplejson.loads(rawr.content)
if response['type'] == "exception":
raise Exception( response["message"] )
self.assert_( "result" in response )
return response['result']
class AuthedTestCase( TestCase ):
fixtures = ["testdb.json"]
def setUp( self ):
# Make sure we always start with a FRESH murmur instance, checking for left-over instances
# and deleting them before creating ours.
try:
self.murmur = Mumble.objects.get( addr="0.0.0.0", port=31337 )
except Mumble.DoesNotExist:
pass
TestCase.setUp( self )
if not self.cl.login( username="svedrin", password="passwort" ):
raise Exception( "Login failed" )
class UnauthedMumbleFormTestCase( ExtDirectFormTestMixin, TestCase ):
api_baseurl = "/mumble/forms"
formname = "MumbleForm"
def testFormGet( self ):
result = self.formGet( [{'pk': 1}] )
self.assertEquals( result['success'], False )
self.assertEquals( result['errors'][''], 'access denied' )
def testFormPost( self ):
result = self.formPost( {'pk': 1, 'url': '', 'player': ''} )
self.assertEquals( result['success'], False )
self.assertEquals( result['errors'][''], 'access denied' )
class AuthedMumbleFormTestCase( ExtDirectFormTestMixin, AuthedTestCase ):
api_baseurl = "/mumble/forms"
formname = "MumbleForm"
def testFormGet( self ):
result = self.formGet( [{'pk': 1}] )
self.assertEquals( result['success'], True, ("errors" in result and result['errors'] or None) )
def testFormPostSrvAdmin( self ):
result = self.formPost( {'pk': 1, 'name': 'test server', 'url': '', 'player': ''} )
self.assertEquals( result['success'], True, ("errors" in result and result['errors'] or None) )
def testFormPostNonSrvAdmin( self ):
result = self.formPost( {'pk': 2, 'name': 'alealejandro', 'url': '', 'player': ''} )
self.assertEquals( result['success'], True, ("errors" in result and result['errors'] or None) )
class UnauthedMumbleUserFormTestCase( ExtDirectFormTestMixin, TestCase ):
api_baseurl = "/mumble/forms"
formname = "MumbleUserForm"
def testFormGet( self ):
result = self.formGet( [{'pk': 1}] )
self.assertEquals( result['success'], False )
self.assertEquals( result['errors'][''], 'access denied' )
def testFormPostWithoutServer( self ):
result = self.formPost( {'pk': 1, 'name': "ohai", 'password': "failfail"} )
self.assertEquals( result['success'], False )
self.assertEquals( result['errors'][''], 'access denied' )
def testFormPost( self ):
result = self.formPost( {'pk': 1, 'name': "svedrin", 'password': 'passwort', 'serverid': 1} )
self.assertEquals( result['success'], False )
self.assertEquals( result['errors'][''], 'access denied' )
class AuthedMumbleUserFormTestCase( ExtDirectFormTestMixin, AuthedTestCase ):
api_baseurl = "/mumble/forms"
formname = "MumbleUserForm"
def testFormGet( self ):
result = self.formGet( [{'pk': 1}] )
self.assertEquals( result['success'], True, ("errors" in result and result['errors'] or None) )
def testFormPostWithoutServer( self ):
result = self.formPost( {'pk': 1, 'name': "svedrin", 'password': 'passwort' } )
self.assertEquals( result['success'], False )
self.assertEquals( result['errors'][''], 'pre-validation failed' )
def testFormPost( self ):
result = self.formPost( {'pk': 1, 'name': "svedrin", 'password': 'passwort', 'serverid': 1} )
self.assertEquals( result['success'], True, ("errors" in result and result['errors'] or None) )
class UnauthedMumbleUserLinkFormTestCase( UnauthedMumbleUserFormTestCase ):
api_baseurl = "/mumble/forms"
formname = "MumbleUserLinkForm"
def testFormGet( self ):
result = self.formGet( [{'pk': 1}] )
self.assertEquals( result['success'], False )
self.assertEquals( result['errors'][''], 'access denied' )
def testFormPost( self ):
result = self.formPost( {'pk': 1, 'name': "ohai", 'password': 'failfail', 'serverid': 1} )
self.assertEquals( result['success'], False )
self.assertEquals( result['errors'][''], 'access denied' )
class AuthedMumbleUserLinkFormTestCase( ExtDirectFormTestMixin, AuthedTestCase ):
api_baseurl = "/mumble/forms"
formname = "MumbleUserLinkForm"
def testFormGet( self ):
if settings.ALLOW_ACCOUNT_LINKING:
# Excepts because linkacc can't be retrieved, but this form is for being
# displayed when empty only so retrieval is either forbidden or an error
self.assertRaises( Exception, self.formGet, [{'pk': 1}] )
else:
self.murmur.delete()
finally:
self.murmur = Mumble( name="#unit testing instance#", addr="0.0.0.0", port=31337 )
self.murmur.save()
def testDefaultConf( self ):
conf = self.murmur.ctl.getAllConf( self.murmur.srvid )
self.assert_( type(conf) == dict )
self.assert_( "host" in conf )
self.assert_( "port" in conf )
self.assert_( "certificate" in conf )
self.assert_( "key" in conf )
self.assert_( "registerhostname" in conf )
self.assert_( "registername" in conf )
self.assert_( "channelname" in conf )
self.assert_( "username" in conf )
self.assert_( "obfuscate" in conf )
self.assert_( "defaultchannel" in conf )
def testAddrPortUnique( self ):
try:
duplicate = Mumble(
name="#another unit testing instance#",
addr=self.murmur.addr, port=self.murmur.port,
dbus=settings.DEFAULT_CONN
)
if duplicate.ctl.method == "ICE":
import Murmur
self.assertRaises( Murmur.ServerFailureException, duplicate.save )
elif self.murmur.version[:2] == [ 1, 2 ]:
from dbus import DBusException
self.assertRaises( DBusException, duplicate.save )
else:
from sqlite3 import IntegrityError
self.assertRaises( IntegrityError, duplicate.save )
finally:
# make sure the duplicate is removed
duplicate.ctl.deleteServer( duplicate.srvid )
def tearDown( self ):
self.murmur.delete()
class DataReading( TestCase ):
""" Tests reading data from murmur using the low-level CTL methods. """
def setUp( self ):
# BIG FAT WARNING: This sucks ass, because it assumes the tester has a
# Murmur database like the one I have.
# I definitely need to prepare Murmur somehow before running these tests.
# Just don't yet know how.
self.murmur = Mumble.objects.get(id=1)
def testCtlGetChannels( self ):
""" Test getChannels() """
channels = self.murmur.ctl.getChannels( self.murmur.srvid )
if self.murmur.ctl.method == "ICE":
import Murmur
self.assertEquals( type( channels[0] ), Murmur.Channel )
result = self.formGet( [{'pk': 1}] )
self.assertEquals( result['success'], False )
self.assertEquals( result['errors'][''], 'access denied' )
def testFormPost( self ):
result = self.formPost( {'pk': 1, 'name': "svedrin", 'password': 'passwort', 'serverid': 1} )
if settings.ALLOW_ACCOUNT_LINKING:
self.assertEquals( result['success'], True, ("errors" in result and result['errors'] or None) )
else:
self.assertEquals( type( channels[0] ), ObjectInfo )
self.assert_( hasattr( channels[0], "id" ) )
self.assert_( hasattr( channels[0], "name" ) )
self.assert_( hasattr( channels[0], "parent" ) )
self.assert_( hasattr( channels[0], "links" ) )
def testCtlGetPlayers( self ):
""" Test getPlayers() """
players = self.murmur.ctl.getPlayers( self.murmur.srvid )
self.assert_( len(players) > 0 )
self.assertEquals( type(players), dict )
for plidx in players:
player = players[plidx]
if self.murmur.ctl.method == "ICE" and self.murmur.version[:2] == ( 1, 2 ):
import Murmur
self.assertEquals( type( player ), Murmur.User )
else:
self.assertEquals( type( player ), ObjectInfo )
self.assert_( hasattr( player, "session" ) )
self.assert_( hasattr( player, "mute" ) )
self.assert_( hasattr( player, "deaf" ) )
self.assert_( hasattr( player, "selfMute" ) )
self.assert_( hasattr( player, "selfDeaf" ) )
self.assert_( hasattr( player, "channel" ) )
self.assert_( hasattr( player, "userid" ) )
self.assert_( hasattr( player, "name" ) )
self.assert_( hasattr( player, "onlinesecs" ) )
self.assert_( hasattr( player, "bytespersec" ) )
def testCtlGetRegisteredPlayers( self ):
""" Test getRegistredPlayers() and getRegistration() """
players = self.murmur.ctl.getRegisteredPlayers( self.murmur.srvid )
self.assert_( len(players) > 0 )
self.assertEquals( type(players), dict )
for plidx in players:
player = players[plidx]
self.assertEquals( type( player ), ObjectInfo )
self.assert_( hasattr( player, "userid" ) )
self.assert_( hasattr( player, "name" ) )
self.assert_( hasattr( player, "email" ) )
self.assert_( hasattr( player, "pw" ) )
# compare with getRegistration result
reg = self.murmur.ctl.getRegistration( self.murmur.srvid, player.userid )
self.assertEquals( type( reg ), ObjectInfo )
self.assert_( hasattr( reg, "userid" ) )
self.assert_( hasattr( reg, "name" ) )
self.assert_( hasattr( reg, "email" ) )
self.assert_( hasattr( reg, "pw" ) )
self.assertEquals( player.userid, reg.userid )
self.assertEquals( player.name, reg.name )
self.assertEquals( player.email, reg.email )
self.assertEquals( player.pw, reg.pw )
def testCtlGetAcl( self ):
""" Test getACL() for the root channel """
acls, groups, inherit = self.murmur.ctl.getACL( self.murmur.srvid, 0 )
for rule in acls:
if self.murmur.ctl.method == "ICE" and self.murmur.version[:2] == ( 1, 2 ):
import Murmur
self.assertEquals( type( rule ), Murmur.ACL )
else:
self.assertEquals( type( rule ), ObjectInfo )
self.assert_( hasattr( rule, "applyHere" ) )
self.assert_( hasattr( rule, "applySubs" ) )
self.assert_( hasattr( rule, "inherited" ) )
self.assert_( hasattr( rule, "userid" ) )
self.assert_( hasattr( rule, "group" ) )
self.assert_( hasattr( rule, "allow" ) )
self.assert_( hasattr( rule, "deny" ) )
for grp in groups:
if self.murmur.ctl.method == "ICE":
import Murmur
self.assertEquals( type( grp ), Murmur.Group )
else:
self.assertEquals( type( grp ), ObjectInfo )
self.assert_( hasattr( grp, "name" ) )
self.assert_( hasattr( grp, "inherited" ) )
self.assert_( hasattr( grp, "inherit" ) )
self.assert_( hasattr( grp, "inheritable" ) )
self.assert_( hasattr( grp, "add" ) )
self.assert_( hasattr( grp, "remove" ) )
self.assert_( hasattr( grp, "members" ) )
self.assertEquals( result['success'], False )
self.assertEquals( result['errors'][''], 'access denied' )
def testFormPostLinking( self ):
result = self.formPost( {'pk': 1, 'name': "svedrin", 'password': 'passwort', 'serverid': 1, 'linkacc': 'on'} )
self.assertEquals( result['success'], False )
class UnauthedFormLoading(TestCase):
""" Makes unauthorized requests to forms which require auth, and checks
that those handle auth correctly.
"""
def setUp(self):
self.cl = Client()
def testMumbleUserFormApi(self):
rawr = self.cl.get( '/mumble/forms/mumbleuserform.js' )
self.assertEquals( rawr.status_code, 200 )
def testMumbleUserPasswordFormApi(self):
rawr = self.cl.get( '/mumble/forms/mumbleuserpasswordform.js' )
self.assertEquals( rawr.status_code, 200 )
def testMumbleUserLinkFormApi(self):
rawr = self.cl.get( '/mumble/forms/mumbleuserlinkform.js' )
self.assertEquals( rawr.status_code, 200 )
def testMumbleAdminFormApi(self):
# This form is NOT exported (and shouldn't be) because it's only used in the admin
rawr = self.cl.get( '/mumble/forms/mumbleadminform.js' )
self.assertEquals( rawr.status_code, 404 )
def testMumbleUserAdminFormApi(self):
# This form is NOT exported (and shouldn't be) because it's only used in the admin
rawr = self.cl.get( '/mumble/forms/mumbleuseradminform.js' )
self.assertEquals( rawr.status_code, 404 )
Loading…
Cancel
Save