diff --git a/evennia/commands/default/account.py b/evennia/commands/default/account.py index 7eda54e75c..5d3b22f090 100644 --- a/evennia/commands/default/account.py +++ b/evennia/commands/default/account.py @@ -162,8 +162,8 @@ class CmdCharCreate(COMMAND_DEFAULT_CLASS): home=default_home, permissions=permissions) # only allow creator (and developers) to puppet this char - new_character.locks.add("puppet:id(%i) or pid(%i) or perm(Developer) or pperm(Developer)" % - (new_character.id, account.id)) + new_character.locks.add("puppet:id(%i) or pid(%i) or perm(Developer) or pperm(Developer);delete:id(%i) or perm(Admin)" % + (new_character.id, account.id, account.id)) account.db._playable_characters.append(new_character) if desc: new_character.db.desc = desc @@ -222,6 +222,12 @@ class CmdCharDelete(COMMAND_DEFAULT_CLASS): match = match[0] account.ndb._char_to_delete = match + + # Return if caller has no permission to delete this + if not match.access(account, 'delete'): + self.msg("You do not have permission to delete this character.") + return + prompt = "|rThis will permanently destroy '%s'. This cannot be undone.|n Continue yes/[no]?" get_input(account, prompt % match.key, _callback) diff --git a/evennia/commands/default/tests.py b/evennia/commands/default/tests.py index 5d2e67ede9..8f9de29ef1 100644 --- a/evennia/commands/default/tests.py +++ b/evennia/commands/default/tests.py @@ -283,6 +283,32 @@ class TestAccount(CommandTest): def test_char_create(self): self.call(account.CmdCharCreate(), "Test1=Test char", "Created new character Test1. Use @ic Test1 to enter the game", caller=self.account) + + def test_char_delete(self): + # Chardelete requires user input; this test is mainly to confirm + # whether permissions are being checked + + # Add char to account playable characters + self.account.db._playable_characters.append(self.char1) + + # Try deleting as Developer + self.call(account.CmdCharDelete(), "Char", "This will permanently destroy 'Char'. This cannot be undone. Continue yes/[no]?", caller=self.account) + + # Downgrade permissions on account + self.account.permissions.add('Player') + self.account.permissions.remove('Developer') + + # Set lock on character object to prevent deletion + self.char1.locks.add('delete:none()') + + # Try deleting as Player + self.call(account.CmdCharDelete(), "Char", "You do not have permission to delete this character.", caller=self.account) + + # Set lock on character object to allow self-delete + self.char1.locks.add('delete:pid(%i)' % self.account.id) + + # Try deleting as Player again + self.call(account.CmdCharDelete(), "Char", "This will permanently destroy 'Char'. This cannot be undone. Continue yes/[no]?", caller=self.account) def test_quell(self): self.call(account.CmdQuell(), "", "Quelling to current puppet's permissions (developer).", caller=self.account) diff --git a/evennia/objects/objects.py b/evennia/objects/objects.py index 0dca98ef75..f44df73df8 100644 --- a/evennia/objects/objects.py +++ b/evennia/objects/objects.py @@ -1894,7 +1894,7 @@ class DefaultCharacter(DefaultObject): """ # lockstring of newly created rooms, for easy overloading. # Will be formatted with the appropriate attributes. - lockstring = "puppet:id({character_id}) or pid({account_id}) or perm(Developer) or pperm(Developer)" + lockstring = "puppet:id({character_id}) or pid({account_id}) or perm(Developer) or pperm(Developer);delete:id({account_id}) or perm(Admin)" @classmethod def create(cls, key, account, **kwargs):