mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
Add .permissions.check() to easily do straight perm-checks without lockstrings
This commit is contained in:
parent
71092f17f7
commit
0556f527fe
2 changed files with 81 additions and 0 deletions
|
|
@ -208,3 +208,39 @@ class TestLockfuncs(EvenniaTest):
|
|||
self.assertEqual(True, lockfuncs.serversetting(None, None, "TESTVAL", "[1, 2, 3]"))
|
||||
self.assertEqual(False, lockfuncs.serversetting(None, None, "TESTVAL", "[1, 2, 4]"))
|
||||
self.assertEqual(False, lockfuncs.serversetting(None, None, "TESTVAL", "123"))
|
||||
|
||||
|
||||
class TestPermissionCheck(EvenniaTest):
|
||||
"""
|
||||
Test the PermissionHandler.check method
|
||||
|
||||
"""
|
||||
def test_check__success(self):
|
||||
"""Test combinations that should pass the check"""
|
||||
self.assertEqual(
|
||||
[perm for perm in self.char1.account.permissions.all()],
|
||||
['developer', 'player']
|
||||
|
||||
)
|
||||
self.assertTrue(self.char1.permissions.check("Builder"))
|
||||
self.assertTrue(self.char1.permissions.check("Builder", "Player"))
|
||||
self.assertTrue(self.char1.permissions.check("Builder", "dummy"))
|
||||
self.assertTrue(self.char1.permissions.check("Developer", "dummy", "foobar"))
|
||||
self.assertTrue(self.char1.permissions.check("Builder", "Player", require_all=True))
|
||||
|
||||
def test_check__fail(self):
|
||||
"""Test combinations that should fail the check"""
|
||||
self.assertFalse(self.char1.permissions.check("dummy"))
|
||||
self.assertFalse(self.char1.permissions.check("Builder", "dummy", require_all=True))
|
||||
self.assertFalse(self.char1.permissions.check("Developer", "foobar", require_all=True))
|
||||
|
||||
self.char1.account.permissions.remove('developer')
|
||||
self.char1.account.permissions.add("Builder")
|
||||
|
||||
self.assertEqual(
|
||||
[perm for perm in self.char1.account.permissions.all()],
|
||||
['builder', 'player']
|
||||
)
|
||||
self.assertFalse(self.char1.permissions.check("Developer"))
|
||||
self.assertFalse(self.char1.permissions.check("Developer", "Player", require_all=True))
|
||||
self.assertFalse(self.char1.permissions.check("Player", "dummy", require_all=True))
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ from collections import defaultdict
|
|||
from django.conf import settings
|
||||
from django.db import models
|
||||
from evennia.utils.utils import to_str, make_iter
|
||||
from evennia.locks.lockfuncs import perm as perm_lockfunc
|
||||
|
||||
|
||||
_TYPECLASS_AGGRESSIVE_CACHE = settings.TYPECLASS_AGGRESSIVE_CACHE
|
||||
|
|
@ -536,3 +537,47 @@ class PermissionHandler(TagHandler):
|
|||
"""
|
||||
|
||||
_tagtype = "permission"
|
||||
|
||||
def check(self, *permissions, require_all=False):
|
||||
"""
|
||||
Straight-up check the provided permission against this handler. The check will pass if
|
||||
|
||||
- any/all given permission exists on the handler (depending on if `require_all` is set).
|
||||
- If handler sits on puppeted object and this is a hierarachical perm, the puppeting
|
||||
Account's permission will also be included in the check, prioritizing the Account's perm
|
||||
(this avoids escalation exploits by puppeting a too-high prio character)
|
||||
- a permission is also considered to exist on the handler, if it is *lower* than
|
||||
a permission on the handler and this is a 'hierarchical' permission given
|
||||
in `settings.PERMISSION_HIERARCHY`. Example: If the 'Developer' hierarchical
|
||||
perm perm is set on the handler, and we check for the 'Builder' perm, the
|
||||
check will pass.
|
||||
|
||||
Args:
|
||||
*permissions (str): Any number of permissions to check. By default,
|
||||
the permission is passed if any of these (or higher, if a
|
||||
hierarchical permission defined in settings.PERMISSION_HIERARCHY)
|
||||
exists in the handler. Permissions are not case-sensitive.
|
||||
require_all (bool): If set, *all* provided permissions much pass
|
||||
the check for the entire check to pass. By default only one
|
||||
needs to pass.
|
||||
|
||||
Returns:
|
||||
bool: If the provided permission(s) pass the check on this handler.
|
||||
|
||||
Example:
|
||||
::
|
||||
can_enter = obj.permissions.check("Blacksmith", "Builder")
|
||||
|
||||
Notes:
|
||||
This works the same way as the `perms` lockfunc and could be
|
||||
replicated with a lock check against the lockstring
|
||||
|
||||
"locktype: perm(perm1) OR perm(perm2) OR ..."
|
||||
|
||||
(using AND for the `require_all` condition).
|
||||
|
||||
"""
|
||||
if require_all:
|
||||
return all(perm_lockfunc(self.obj, None, perm) for perm in permissions)
|
||||
else:
|
||||
return any(perm_lockfunc(self.obj, None, perm) for perm in permissions)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue