Browse Source

properly implement ACL handling

Natenom/support-murmur-13-1446181288462
Michael Ziegler 15 years ago
parent
commit
368c137a61
  1. 43
      pyweb/mumble/MumbleCtlDbus.py
  2. 119
      pyweb/mumble/MumbleCtlIce.py
  3. 2
      pyweb/mumble/mctl.py
  4. 90
      pyweb/mumble/mmobjects.py
  5. 29
      pyweb/mumble/models.py

43
pyweb/mumble/MumbleCtlDbus.py

@ -135,10 +135,47 @@ class MumbleCtlDbus_118(MumbleCtlBase):
return MumbleCtlDbus_118.convertDbusTypeToNative(self._getDbusServerObject(srvid).getRegisteredPlayers( filter ) )
def getACL(self, srvid, channelid):
return MumbleCtlDbus_118.convertDbusTypeToNative(self._getDbusServerObject(srvid).getACL(channelid))
raw_acls, raw_groups, raw_inherit = self._getDbusServerObject(srvid).getACL(channelid)
acls = [ ObjectInfo(
applyHere = bool(rule[0]),
applySubs = bool(rule[1]),
inherited = bool(rule[2]),
userid = int(rule[3]),
group = str(rule[4]),
allow = int(rule[5]),
deny = int(rule[6]),
)
for rule in raw_acls
];
groups = [ ObjectInfo(
name = str(group[0]),
inherited = bool(group[1]),
inherit = bool(group[2]),
inheritable = bool(group[3]),
add = [ int(usrid) for usrid in group[4] ],
remove = [ int(usrid) for usrid in group[5] ],
members = [ int(usrid) for usrid in group[6] ],
)
for group in raw_groups
];
return acls, groups, bool(raw_inherit);
def setACL(self, srvid, acl):
self._getDbusServerObject(srvid).setACL(*acl.pack())
def setACL(self, srvid, channelid, acls, groups, inherit):
# Pack acl ObjectInfo into a tuple and send that over dbus
dbus_acls = [
( rule.applyHere, rule.applySubs, rule.inherited, rule.userid, rule.group, rule.allow, rule.deny )
for rule in acls
];
dbus_groups = [
( group.name, group.inherited, group.inherit, group.inheritable, group.add, group.remove, group.members )
for group in groups
];
return self._getDbusServerObject(srvid).setACL( channelid, dbus_acls, dbus_groups, inherit );
def getBootedServers(self):
return MumbleCtlDbus_118.convertDbusTypeToNative(self.meta.getBootedServers())

119
pyweb/mumble/MumbleCtlIce.py

@ -195,54 +195,41 @@ class MumbleCtlIce_118(MumbleCtlBase):
@protectDjangoErrPage
def getACL(self, srvid, channelid):
import Murmur
acls = self._getIceServerObject(srvid).getACL(channelid)
ret = []
for x in acls:
if isinstance(x, list):
tmp = []
for y in x:
if y.__class__ is Murmur.ACL:
tmp.append([y.applyHere, y.applySubs, y.inherited, y.playerid, self.setUnicodeFlag(y.group), y.allow, y.deny])
elif y.__class__ is Murmur.Group:
tmp.append([self.setUnicodeFlag(y.name), y.inherited, y.inherit, y.inheritable, y.add, y.remove, y.members])
ret.append(tmp)
else:
ret.append(x)
# need to convert acls to say "userid" instead of "playerid". meh.
raw_acls, raw_groups, raw_inherit = self._getIceServerObject(srvid).getACL(channelid)
return ret
acls = [ ObjectInfo(
applyHere = rule.applyHere,
applySubs = rule.applySubs,
inherited = rule.inherited,
userid = rule.playerid,
group = rule.group,
allow = rule.allow,
deny = rule.deny,
)
for rule in raw_acls
];
return acls, raw_groups, raw_inherit;
@protectDjangoErrPage
def setACL(self, srvid, acl):
def setACL(self, srvid, channelid, acls, groups, inherit):
import Murmur
newacls = [];
newgroups = [];
ice_acls = [];
for curr_acl in acl.acls:
new_acl = Murmur.ACL();
new_acl.applyHere = curr_acl['applyHere'];
new_acl.applySubs = curr_acl['applySubs'];
new_acl.inherited = curr_acl['inherited'];
new_acl.playerid = curr_acl['playerid'];
new_acl.group = curr_acl['group'].encode( "UTF-8" );
new_acl.allow = curr_acl['allow'];
new_acl.deny = curr_acl['deny'];
newacls.append( new_acl );
for rule in acls:
ice_rule = Murmur.ACL();
ice_rule.applyHere = rule.applyHere;
ice_rule.applySubs = rule.applySubs;
ice_rule.inherited = rule.inherited;
ice_rule.playerid = rule.userid;
ice_rule.group = rule.group;
ice_rule.allow = rule.allow;
ice_rule.deny = rule.deny;
ice_acls.append(ice_rule);
for curr_group in acl.groups:
new_group = Murmur.Group()
new_group.name = curr_group['name'].encode( "UTF-8" );
new_group.inherited = curr_group['inherited'];
new_group.inherit = curr_group['inherit'];
new_group.inheritable = curr_group['inheritable'];
new_group.add = curr_group['add'];
new_group.remove = curr_group['remove'];
new_group.members = curr_group['members'];
newgroups.append( new_group );
self._getIceServerObject(srvid).setACL( acl.channelId, newacls, newgroups, acl.inherit );
return self._getIceServerObject(srvid).setACL( channelid, ice_acls, groups, inherit );
@protectDjangoErrPage
def getTexture(self, srvid, mumbleid):
@ -359,53 +346,9 @@ class MumbleCtlIce_120(MumbleCtlIce_118):
@protectDjangoErrPage
def getACL(self, srvid, channelid):
import Murmur
acls = self._getIceServerObject(srvid).getACL(channelid)
ret = []
for x in acls:
if isinstance(x, list):
tmp = []
for y in x:
if y.__class__ is Murmur.ACL:
tmp.append([y.applyHere, y.applySubs, y.inherited, y.userid, self.setUnicodeFlag(y.group), y.allow, y.deny])
elif y.__class__ is Murmur.Group:
tmp.append([self.setUnicodeFlag(y.name), y.inherited, y.inherit, y.inheritable, y.add, y.remove, y.members])
ret.append(tmp)
else:
ret.append(x)
return ret
return self._getIceServerObject(srvid).getACL(channelid)
@protectDjangoErrPage
def setACL(self, srvid, acl):
import Murmur
newacls = [];
newgroups = [];
for curr_acl in acl.acls:
new_acl = Murmur.ACL();
new_acl.applyHere = curr_acl['applyHere'];
new_acl.applySubs = curr_acl['applySubs'];
new_acl.inherited = curr_acl['inherited'];
new_acl.userid = curr_acl['playerid'];
new_acl.group = curr_acl['group'].encode( "UTF-8" );
new_acl.allow = curr_acl['allow'];
new_acl.deny = curr_acl['deny'];
newacls.append( new_acl );
for curr_group in acl.groups:
new_group = Murmur.Group()
new_group.name = curr_group['name'].encode( "UTF-8" );
new_group.inherited = curr_group['inherited'];
new_group.inherit = curr_group['inherit'];
new_group.inheritable = curr_group['inheritable'];
new_group.add = curr_group['add'];
new_group.remove = curr_group['remove'];
new_group.members = curr_group['members'];
newgroups.append( new_group );
self._getIceServerObject(srvid).setACL( acl.channelId, newacls, newgroups, acl.inherit );
def setACL(self, srvid, channelid, acls, groups, inherit):
return self._getIceServerObject(srvid).setACL( channelid, acls, groups, inherit );

2
pyweb/mumble/mctl.py

@ -82,7 +82,7 @@ class MumbleCtlBase (object):
def getACL(self, srvid, channelid):
raise NotImplementedError( "mctl::getACL" );
def setACL(self, srvid, acl):
def setACL(self, srvid, channelid, acl, groups, inherit):
raise NotImplementedError( "mctl::setACL" );
def getTexture(self, srvid, mumbleid):

90
pyweb/mumble/mmobjects.py

@ -43,6 +43,8 @@ class mmChannel( object ):
self.parent = parentChan;
if self.parent is not None:
self.parent.subchans.append( self );
self._acl = None;
# Lookup unknown attributes in self.channelObj to automatically include Murmur's fields
def __getattr__( self, key ):
@ -58,6 +60,16 @@ class mmChannel( object ):
return self.parent.parentChannels() + [self.parent.name];
def getACL( self ):
""" Retrieve the ACL for this channel. """
if not self._acl:
self._acl = mmACL( self, self.server.ctl.getACL( self.server.srvid, self.chanid ) );
return self._acl;
acl = property( getACL, doc=getACL.__doc__ );
is_server = False;
is_channel = True;
is_player = False;
@ -213,34 +225,56 @@ class mmPlayer( object ):
class mmACL:
"""Represents an ACL for a certain channel."""
def __init__( self, channelId, aclObj ):
aclsrc, groupsrc, inherit = aclObj;
self.channelId = channelId;
self.acls = [];
for line in aclsrc:
acl = {};
acl['applyHere'], acl['applySubs'], acl['inherited'], acl['playerid'], acl['group'], acl['allow'], acl['deny'] = line;
self.acls.append( acl );
self.groups = [];
for line in groupsrc:
group = {};
group['name'], group['inherited'], group['inherit'], group['inheritable'], group['add'], group['remove'], group['members'] = line;
self.groups.append( group );
if group['name'] == "admin":
self.admingroup = group;
self.inherit = inherit;
def pack( self ):
""" Pack the information in this ACL up in a way that it can be passed to DBus. """
return (
self.channelId,
[( acl['applyHere'], acl['applySubs'], acl['inherited'], acl['playerid'], acl['group'], acl['allow'], acl['deny'] ) for acl in self.acls ],
[( group['name'], group['inherited'], group['inherit'], group['inheritable'], group['add'], group['remove'], group['members'] ) for group in self.groups ],
self.inherit
def __init__( self, channel, aclObj ):
self.channel = channel;
self.acls, self.groups, self.inherit = aclObj;
self.groups_dict = {};
for group in self.groups:
self.groups_dict[ group.name ] = group;
def groupHasMember( self, name, userid ):
""" Checks if the given userid is a member of the given group in this channel. """
if name not in self.groups_dict:
raise ReferenceError( "No such group '%s'" % name );
return userid in self.groups_dict[name].add or userid in self.groups_dict[name].members;
def groupAddMember( self, name, userid ):
""" Make sure this userid is a member of the group in this channel (and subs). """
if name not in self.groups_dict:
raise ReferenceError( "No such group '%s'" % name );
group = self.groups_dict[name];
# if neither inherited nor to be added, add
if userid not in group.members and userid not in group.add:
group.add.append( userid );
# if to be removed, unremove
if userid in group.remove:
group.remove.remove( userid );
def groupRemoveMember( self, name, userid ):
""" Make sure this userid is NOT a member of the group in this channel (and subs). """
if name not in self.groups_dict:
raise ReferenceError( "No such group '%s'" % name );
group = self.groups_dict[name];
# if added here, unadd
if userid in group.add:
group.add.remove( userid );
# if member and not in remove, add to remove
elif userid in group.members and userid not in group.remove:
group.remove.append( userid );
def save( self ):
return self.channel.server.ctl.setACL(
self.channel.server.srvid,
self.channel.chanid,
self.acls, self.groups, self.inherit
);

29
pyweb/mumble/models.py

@ -446,39 +446,28 @@ class MumbleUser( models.Model ):
# Don't save the users' passwords, we don't need them anyway
self.password = '';
self.setAdmin( self.isAdmin );
self.aclAdmin = self.isAdmin;
# Now allow django to save the record set
return models.Model.save( self );
# Admin handlers
def getAdmin( self ):
"""Get ACL of root Channel, get the admin group and see if this user is in it."""
acl = mmACL( 0, self.server.ctl.getACL(self.server.srvid, 0) );
if not hasattr( acl, "admingroup" ):
raise ReferenceError( _( "The admin group was not found in the ACL's groups list!" ) );
return self.mumbleid in acl.admingroup['add'];
return self.server.rootchan.acl.groupHasMember( "admin", self.mumbleid );
def setAdmin( self, value ):
"""Set or revoke this user's membership in the admin group on the root channel."""
ctl = self.server.ctl;
acl = mmACL( 0, ctl.getACL(self.server.srvid, 0) );
if not hasattr( acl, "admingroup" ):
raise ReferenceError( _( "The admin group was not found in the ACL's groups list!" ) );
if value != ( self.mumbleid in acl.admingroup['add'] ):
if value:
acl.admingroup['add'].append( self.mumbleid );
else:
acl.admingroup['add'].remove( self.mumbleid );
ctl.setACL(self.server.srvid, acl);
if value:
self.server.rootchan.acl.groupAddMember( "admin", self.mumbleid );
else:
self.server.rootchan.acl.groupRemoveMember( "admin", self.mumbleid );
self.server.rootchan.acl.save();
return value;
aclAdmin = property( getAdmin, setAdmin, doc="Wrapper around getAdmin/setAdmin (not a database field like isAdmin)" );
# Registration fetching
def getRegistration( self ):
"""Retrieve a user's registration from Murmur as a dict."""

Loading…
Cancel
Save