Added Character-level quelling possibilities to superuser. This makes the superuser quelling completely in line with normal quelling for other permission levels. It also removes the need for the special _superuser_character bypass used before (the migration no longer creates it an initial_setup won't either).

This commit is contained in:
Griatch 2013-05-14 14:53:08 +02:00
parent 77a0b47859
commit f00053710c
5 changed files with 30 additions and 33 deletions

View file

@ -109,18 +109,13 @@ class CmdOOCLook(MuxPlayerCommand):
# character is already puppeted
sess = player.get_session(csessid)
sid = sess in sessions and sessions.index(sess) + 1
if hasattr(char.locks, "lock_bypass") and char.locks.lock_bypass:
string += "\n - {G%s{n [superuser character] (played by you in session %i)" % (char.key, sid)
elif sess:
if sess:
string += "\n - {G%s{n [%s] (played by you in session %i)" % (char.key, ", ".join(char.permissions), sid)
else:
string += "\n - {R%s{n [%s] (played by someone else)" % (char.key, ", ".join(char.permissions))
else:
# character is "free to puppet"
if player.is_superuser and char.get_attribute("_superuser_character"):
string += "\n - %s [superuser character]" % (char.key)
else:
string += "\n - %s [%s]" % (char.key, ", ".join(char.permissions))
string += "\n - %s [%s]" % (char.key, ", ".join(char.permissions))
string = ("-" * 68) + "\n" + string + "\n" + ("-" * 68)
self.msg(string)
@ -629,26 +624,30 @@ class CmdQuell(MuxPlayerCommand):
locks = "cmd:all()"
help_category = "General"
def _recache_locks(self, player):
"Helper method to reset the lockhandler on an already puppeted object"
if self.sessid:
char = player.get_puppet(self.sessid)
if char:
# we are already puppeting an object. We need to reset the lock caches
# (otherwise the superuser status change won't be visible until repuppet)
char.locks.reset()
def func(self):
"Perform the command"
player = self.caller
permstr = " (%s)" % (", ".join(player.permissions))
if player.is_superuser:
self.msg("Superusers cannot be quelled.")
return
permstr = player.is_superuser and " (superuser)" or " (%s)" % (", ".join(player.permissions))
if self.cmdstring == '@unquell':
if not player.get_attribute('_quell'):
self.msg("Already using normal Player permissions%s." % permstr)
else:
player.del_attribute('_quell')
self.msg("Player permissions restored%s." % permstr)
return
self.msg("Player permissions%s restored." % permstr)
else:
if player.get_attribute('_quell'):
self.msg("Already quelling Player permissions")
self.msg("Already quelling Player%s permissions." % permstr)
return
player.set_attribute('_quell', True)
self.msg("Quelling Player permissions%s." % permstr)
return
self.msg("Quelling Player%s permissions. Use @unquell to get them back." % permstr)
self._recache_locks(player)
return

View file

@ -259,7 +259,6 @@ class LockHandler(object):
get_player method (this sits on serversessions, in some rare cases where a check is done
before the login process has yet been fully finalized)
"""
#print "_superuser_character:", hasattr(obj, "get_attribute") and obj.get_attribute("_superuser_character")
self.lock_bypass = hasattr(obj, "is_superuser") and obj.is_superuser
def add(self, lockstring, log_obj=None):
@ -363,9 +362,10 @@ class LockHandler(object):
"""
if self.reset_flag:
# on-demand cache rebuild
# rebuild cache, either directly or next call
self._cache_locks(self.obj.lock_storage)
self.reset_flag = False
self.cache_lock_bypass(self.obj)
try:
# check if the lock should be bypassed (e.g. superuser status)

View file

@ -497,7 +497,7 @@ class ObjectDB(TypedObject):
def __is_superuser_get(self):
"Check if user has a player, and if so, if it is a superuser."
return (_GA(self, "db_player") and _GA(_GA(self, "db_player"), "is_superuser")
and _GA(self, "get_attribute")("_superuser_character"))
and not _GA(_GA(self, "db_player"), "get_attribute")("_quell"))
is_superuser = property(__is_superuser_get)
# contents

View file

@ -28,7 +28,7 @@ class Migration(DataMigration):
# Note: Remember to use orm['appname.ModelName'] rather than "from appname.models..."
lockstring = "attrread:perm(Admins);attredit:perm(Admins);attrcreate:perm(Admins)"
lockstring2 = "attrread:false();attredit:false();attrcreate:false()"
#lockstring2 = "attrread:false();attredit:false();attrcreate:false()"
if not db.dry_run:
for player in orm['players.PlayerDB'].objects.all():
char = player.db_obj
@ -47,14 +47,15 @@ class Migration(DataMigration):
db_value=val)
suser = char and char.id == 1
if suser:
# move the superuser unmask attribute for the superuser (note that this
# is not a security risk, it only works if player's superuser bit is set too)
val = pickle.dumps(("simple", suser))
orm['objects.ObjAttribute'].objects.create(db_key="_superuser_character",
db_obj=char,
db_lock_storage=lockstring2,
db_value=val)
#if suser:
# # REMOVED - this is not needed - Griatch
# # the superuser unmask attribute for the superuser (note that this
# # is not a security risk, it only works if player's superuser bit is set too)
# val = pickle.dumps(("simple", suser))
# orm['objects.ObjAttribute'].objects.create(db_key="_superuser_character",
# db_obj=char,
# db_lock_storage=lockstring2,
# db_value=val)
def backwards(self, orm):

View file

@ -58,12 +58,9 @@ def create_objects():
god_character.id = 1
god_character.db.desc = _('This is User #1.')
god_character.locks.add("examine:perm(Immortals);edit:false();delete:false();boot:false();msg:all();puppet:false()")
god_character.permissions = "Immortals"
god_character.save()
# note that there is no security issue with setting the _superuser_character flag - the system
# will only grant superuser access to a character with this flag if its Player also has the
# superuser bit set. It only marks that the character should not "mask" the superuser privileges.
god_character.set_attribute("_superuser_character", True)
god_player.set_attribute("_first_login", True)
god_player.set_attribute("_last_puppet", god_character)
god_player.db._playable_characters.append(god_character)