From f00053710c3340710f3c00284546e758f187e08c Mon Sep 17 00:00:00 2001 From: Griatch Date: Tue, 14 May 2013 14:53:08 +0200 Subject: [PATCH] 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). --- src/commands/default/player.py | 33 +++++++++---------- src/locks/lockhandler.py | 4 +-- src/objects/models.py | 2 +- .../0014_add_attr__playable_characters.py | 19 ++++++----- src/server/initial_setup.py | 5 +-- 5 files changed, 30 insertions(+), 33 deletions(-) diff --git a/src/commands/default/player.py b/src/commands/default/player.py index ad578e5ca..8dc667df6 100644 --- a/src/commands/default/player.py +++ b/src/commands/default/player.py @@ -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 diff --git a/src/locks/lockhandler.py b/src/locks/lockhandler.py index c55fed1a6..2feae6e27 100644 --- a/src/locks/lockhandler.py +++ b/src/locks/lockhandler.py @@ -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) diff --git a/src/objects/models.py b/src/objects/models.py index fa22afbf1..a67503c94 100644 --- a/src/objects/models.py +++ b/src/objects/models.py @@ -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 diff --git a/src/players/migrations/0014_add_attr__playable_characters.py b/src/players/migrations/0014_add_attr__playable_characters.py index 285a82548..5e43d416b 100644 --- a/src/players/migrations/0014_add_attr__playable_characters.py +++ b/src/players/migrations/0014_add_attr__playable_characters.py @@ -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): diff --git a/src/server/initial_setup.py b/src/server/initial_setup.py index f85405151..dc0326fe7 100644 --- a/src/server/initial_setup.py +++ b/src/server/initial_setup.py @@ -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)