Merge with develop and fix merge conflicts

This commit is contained in:
Griatch 2018-10-01 20:58:16 +02:00
commit 72f4fedcbe
148 changed files with 20005 additions and 2718 deletions

View file

@ -89,10 +89,14 @@ DefaultLock: Exits: controls who may traverse the exit to
"""
from ast import literal_eval
from django.conf import settings
from evennia.utils import utils
_PERMISSION_HIERARCHY = [pe.lower() for pe in settings.PERMISSION_HIERARCHY]
# also accept different plural forms
_PERMISSION_HIERARCHY_PLURAL = [pe + 's' if not pe.endswith('s') else pe
for pe in _PERMISSION_HIERARCHY]
def _to_account(accessing_obj):
@ -158,49 +162,77 @@ def perm(accessing_obj, accessed_obj, *args, **kwargs):
"""
# this allows the perm_above lockfunc to make use of this function too
gtmode = kwargs.pop("_greater_than", False)
try:
permission = args[0].lower()
perms_object = [p.lower() for p in accessing_obj.permissions.all()]
perms_object = accessing_obj.permissions.all()
except (AttributeError, IndexError):
return False
if utils.inherits_from(accessing_obj, "evennia.objects.objects.DefaultObject") and accessing_obj.account:
account = accessing_obj.account
# we strip eventual plural forms, so Builders == Builder
perms_account = [p.lower().rstrip("s") for p in account.permissions.all()]
gtmode = kwargs.pop("_greater_than", False)
is_quell = False
account = (utils.inherits_from(accessing_obj, "evennia.objects.objects.DefaultObject") and
accessing_obj.account)
# check object perms (note that accessing_obj could be an Account too)
perms_account = []
if account:
perms_account = account.permissions.all()
is_quell = account.attributes.get("_quell")
if permission in _PERMISSION_HIERARCHY:
# check hierarchy without allowing escalation obj->account
hpos_target = _PERMISSION_HIERARCHY.index(permission)
hpos_account = [hpos for hpos, hperm in enumerate(_PERMISSION_HIERARCHY) if hperm in perms_account]
# Check hirarchy matches; handle both singular/plural forms in hierarchy
hpos_target = None
if permission in _PERMISSION_HIERARCHY:
hpos_target = _PERMISSION_HIERARCHY.index(permission)
if permission.endswith('s') and permission[:-1] in _PERMISSION_HIERARCHY:
hpos_target = _PERMISSION_HIERARCHY.index(permission[:-1])
if hpos_target is not None:
# hieratchy match
hpos_account = -1
hpos_object = -1
if account:
# we have an account puppeting this object. We must check what perms it has
perms_account_single = [p[:-1] if p.endswith('s') else p for p in perms_account]
hpos_account = [hpos for hpos, hperm in enumerate(_PERMISSION_HIERARCHY)
if hperm in perms_account_single]
hpos_account = hpos_account and hpos_account[-1] or -1
if is_quell:
hpos_object = [hpos for hpos, hperm in enumerate(_PERMISSION_HIERARCHY) if hperm in perms_object]
hpos_object = hpos_object and hpos_object[-1] or -1
if gtmode:
return hpos_target < min(hpos_account, hpos_object)
else:
return hpos_target <= min(hpos_account, hpos_object)
elif gtmode:
if not account or is_quell:
# only get the object-level perms if there is no account or quelling
perms_object_single = [p[:-1] if p.endswith('s') else p for p in perms_object]
hpos_object = [hpos for hpos, hperm in enumerate(_PERMISSION_HIERARCHY)
if hperm in perms_object_single]
hpos_object = hpos_object and hpos_object[-1] or -1
if account and is_quell:
# quell mode: use smallest perm from account and object
if gtmode:
return hpos_target < min(hpos_account, hpos_object)
else:
return hpos_target <= min(hpos_account, hpos_object)
elif account:
# use account perm
if gtmode:
return hpos_target < hpos_account
else:
return hpos_target <= hpos_account
elif not is_quell and permission in perms_account:
# if we get here, check account perms first, otherwise
# continue as normal
else:
# use object perm
if gtmode:
return hpos_target < hpos_object
else:
return hpos_target <= hpos_object
else:
# no hierarchy match - check direct matches
if account:
# account exists, check it first unless quelled
if is_quell and permission in perms_object:
return True
elif permission in perms_account:
return True
elif permission in perms_object:
return True
if permission in perms_object:
# simplest case - we have direct match
return True
if permission in _PERMISSION_HIERARCHY:
# check if we have a higher hierarchy position
hpos_target = _PERMISSION_HIERARCHY.index(permission)
return any(1 for hpos, hperm in enumerate(_PERMISSION_HIERARCHY)
if hperm in perms_object and hpos_target < hpos)
return False
@ -229,7 +261,6 @@ def pperm(accessing_obj, accessed_obj, *args, **kwargs):
"""
return perm(_to_account(accessing_obj), accessed_obj, *args, **kwargs)
def pperm_above(accessing_obj, accessed_obj, *args, **kwargs):
"""
Only allow Account objects with a permission *higher* in the permission
@ -482,7 +513,7 @@ def tag(accessing_obj, accessed_obj, *args, **kwargs):
accessing_obj = accessing_obj.obj
tagkey = args[0] if args else None
category = args[1] if len(args) > 1 else None
return accessing_obj.tags.get(tagkey, category=category)
return bool(accessing_obj.tags.get(tagkey, category=category))
def objtag(accessing_obj, accessed_obj, *args, **kwargs):
@ -494,7 +525,7 @@ def objtag(accessing_obj, accessed_obj, *args, **kwargs):
Only true if accessed_obj has the specified tag and optional
category.
"""
return accessed_obj.tags.get(*args)
return bool(accessed_obj.tags.get(*args))
def inside(accessing_obj, accessed_obj, *args, **kwargs):
@ -592,7 +623,9 @@ def serversetting(accessing_obj, accessed_obj, *args, **kwargs):
serversetting(IRC_ENABLED)
serversetting(BASE_SCRIPT_PATH, ['types'])
A given True/False or integers will be converted properly.
A given True/False or integers will be converted properly. Note that
everything will enter this function as strings, so they have to be
unpacked to their real value. We only support basic properties.
"""
if not args or not args[0]:
return False
@ -602,12 +635,12 @@ def serversetting(accessing_obj, accessed_obj, *args, **kwargs):
else:
setting, val = args[0], args[1]
# convert
if val == 'True':
val = True
elif val == 'False':
val = False
elif val.isdigit():
val = int(val)
try:
val = literal_eval(val)
except Exception:
# we swallow errors here, lockfuncs has noone to report to
return False
if setting in settings._wrapped.__dict__:
return settings._wrapped.__dict__[setting] == val
return False

View file

@ -114,6 +114,9 @@ from django.utils.translation import ugettext as _
__all__ = ("LockHandler", "LockException")
WARNING_LOG = settings.LOCKWARNING_LOG_FILE
_LOCK_HANDLER = None
#
# Exception class. This will be raised
@ -287,7 +290,7 @@ class LockHandler(object):
"""
self.lock_bypass = hasattr(obj, "is_superuser") and obj.is_superuser
def add(self, lockstring):
def add(self, lockstring, validate_only=False):
"""
Add a new lockstring to handler.
@ -296,10 +299,12 @@ class LockHandler(object):
`"<access_type>:<functions>"`. Multiple access types
should be separated by semicolon (`;`). Alternatively,
a list with lockstrings.
validate_only (bool, optional): If True, validate the lockstring but
don't actually store it.
Returns:
success (bool): The outcome of the addition, `False` on
error.
error. If `validate_only` is True, this will be a tuple
(bool, error), for pass/fail and a string error.
"""
if isinstance(lockstring, str):
@ -308,21 +313,41 @@ class LockHandler(object):
lockdefs = [lockdef for locks in lockstring for lockdef in locks.split(";")]
lockstring = ";".join(lockdefs)
err = ""
# sanity checks
for lockdef in lockdefs:
if ':' not in lockdef:
self._log_error(_("Lock: '%s' contains no colon (:).") % lockdef)
return False
err = _("Lock: '{lockdef}' contains no colon (:).").format(lockdef=lockdef)
if validate_only:
return False, err
else:
self._log_error(err)
return False
access_type, rhs = [part.strip() for part in lockdef.split(':', 1)]
if not access_type:
self._log_error(_("Lock: '%s' has no access_type (left-side of colon is empty).") % lockdef)
return False
err = _("Lock: '{lockdef}' has no access_type "
"(left-side of colon is empty).").format(lockdef=lockdef)
if validate_only:
return False, err
else:
self._log_error(err)
return False
if rhs.count('(') != rhs.count(')'):
self._log_error(_("Lock: '%s' has mismatched parentheses.") % lockdef)
return False
err = _("Lock: '{lockdef}' has mismatched parentheses.").format(lockdef=lockdef)
if validate_only:
return False, err
else:
self._log_error(err)
return False
if not _RE_FUNCS.findall(rhs):
self._log_error(_("Lock: '%s' has no valid lock functions.") % lockdef)
return False
err = _("Lock: '{lockdef}' has no valid lock functions.").format(lockdef=lockdef)
if validate_only:
return False, err
else:
self._log_error(err)
return False
if validate_only:
return True, None
# get the lock string
storage_lockstring = self.obj.lock_storage
if storage_lockstring:
@ -334,6 +359,18 @@ class LockHandler(object):
self._save_locks()
return True
def validate(self, lockstring):
"""
Validate lockstring syntactically, without saving it.
Args:
lockstring (str): Lockstring to validate.
Returns:
valid (bool): If validation passed or not.
"""
return self.add(lockstring, validate_only=True)
def replace(self, lockstring):
"""
Replaces the lockstring entirely.
@ -421,6 +458,28 @@ class LockHandler(object):
self._cache_locks(self.obj.lock_storage)
self.cache_lock_bypass(self.obj)
def append(self, access_type, lockstring, op='or'):
"""
Append a lock definition to access_type if it doesn't already exist.
Args:
access_type (str): Access type.
lockstring (str): A valid lockstring, without the operator to
link it to an eventual existing lockstring.
op (str): An operator 'and', 'or', 'and not', 'or not' used
for appending the lockstring to an existing access-type.
Note:
The most common use of this method is for use in commands where
the user can specify their own lockstrings. This method allows
the system to auto-add things like Admin-override access.
"""
old_lockstring = self.get(access_type)
if not lockstring.strip().lower() in old_lockstring.lower():
lockstring = "{old} {op} {new}".format(
old=old_lockstring, op=op, new=lockstring.strip())
self.add(lockstring)
def check(self, accessing_obj, access_type, default=False, no_superuser_bypass=False):
"""
Checks a lock of the correct type by passing execution off to
@ -459,9 +518,13 @@ class LockHandler(object):
return True
except AttributeError:
# happens before session is initiated.
if not no_superuser_bypass and ((hasattr(accessing_obj, 'is_superuser') and accessing_obj.is_superuser) or
(hasattr(accessing_obj, 'account') and hasattr(accessing_obj.account, 'is_superuser') and accessing_obj.account.is_superuser) or
(hasattr(accessing_obj, 'get_account') and (not accessing_obj.get_account() or accessing_obj.get_account().is_superuser))):
if not no_superuser_bypass and (
(hasattr(accessing_obj, 'is_superuser') and accessing_obj.is_superuser) or
(hasattr(accessing_obj, 'account') and
hasattr(accessing_obj.account, 'is_superuser') and
accessing_obj.account.is_superuser) or
(hasattr(accessing_obj, 'get_account') and
(not accessing_obj.get_account() or accessing_obj.get_account().is_superuser))):
return True
# no superuser or bypass -> normal lock operation
@ -469,7 +532,8 @@ class LockHandler(object):
# we have a lock, test it.
evalstring, func_tup, raw_string = self.locks[access_type]
# execute all lock funcs in the correct order, producing a tuple of True/False results.
true_false = tuple(bool(tup[0](accessing_obj, self.obj, *tup[1], **tup[2])) for tup in func_tup)
true_false = tuple(bool(
tup[0](accessing_obj, self.obj, *tup[1], **tup[2])) for tup in func_tup)
# the True/False tuple goes into evalstring, which combines them
# with AND/OR/NOT in order to get the final result.
return eval(evalstring % true_false)
@ -520,9 +584,13 @@ class LockHandler(object):
if accessing_obj.locks.lock_bypass and not no_superuser_bypass:
return True
except AttributeError:
if no_superuser_bypass and ((hasattr(accessing_obj, 'is_superuser') and accessing_obj.is_superuser) or
(hasattr(accessing_obj, 'account') and hasattr(accessing_obj.account, 'is_superuser') and accessing_obj.account.is_superuser) or
(hasattr(accessing_obj, 'get_account') and (not accessing_obj.get_account() or accessing_obj.get_account().is_superuser))):
if no_superuser_bypass and (
(hasattr(accessing_obj, 'is_superuser') and accessing_obj.is_superuser) or
(hasattr(accessing_obj, 'account') and
hasattr(accessing_obj.account, 'is_superuser') and
accessing_obj.account.is_superuser) or
(hasattr(accessing_obj, 'get_account') and
(not accessing_obj.get_account() or accessing_obj.get_account().is_superuser))):
return True
if ":" not in lockstring:
lockstring = "%s:%s" % ("_dummy", lockstring)
@ -538,7 +606,81 @@ class LockHandler(object):
else:
# if no access types was given and multiple locks were
# embedded in the lockstring we assume all must be true
return all(self._eval_access_type(accessing_obj, locks, access_type) for access_type in locks)
return all(self._eval_access_type(
accessing_obj, locks, access_type) for access_type in locks)
# convenience access function
# dummy to be able to call check_lockstring from the outside
class _ObjDummy:
lock_storage = ''
def check_lockstring(self, accessing_obj, lockstring, no_superuser_bypass=False,
default=False, access_type=None):
"""
Do a direct check against a lockstring ('atype:func()..'),
without any intermediary storage on the accessed object.
Args:
accessing_obj (object or None): The object seeking access.
Importantly, this can be left unset if the lock functions
don't access it, no updating or storage of locks are made
against this object in this method.
lockstring (str): Lock string to check, on the form
`"access_type:lock_definition"` where the `access_type`
part can potentially be set to a dummy value to just check
a lock condition.
no_superuser_bypass (bool, optional): Force superusers to heed lock.
default (bool, optional): Fallback result to use if `access_type` is set
but no such `access_type` is found in the given `lockstring`.
access_type (str, bool): If set, only this access_type will be looked up
among the locks defined by `lockstring`.
Return:
access (bool): If check is passed or not.
"""
global _LOCKHANDLER
if not _LOCKHANDLER:
_LOCKHANDLER = LockHandler(_ObjDummy())
return _LOCK_HANDLER.check_lockstring(
accessing_obj, lockstring, no_superuser_bypass=no_superuser_bypass,
default=default, access_type=access_type)
def validate_lockstring(lockstring):
"""
Validate so lockstring is on a valid form.
Args:
lockstring (str): Lockstring to validate.
Returns:
is_valid (bool): If the lockstring is valid or not.
error (str or None): A string describing the error, or None
if no error was found.
"""
global _LOCK_HANDLER
if not _LOCK_HANDLER:
_LOCK_HANDLER = LockHandler(_ObjDummy())
return _LOCK_HANDLER.validate(lockstring)
def get_all_lockfuncs():
"""
Get a dict of available lock funcs.
Returns:
lockfuncs (dict): Mapping {lockfuncname:func}.
"""
if not _LOCKFUNCS:
_cache_lockfuncs()
return _LOCKFUNCS
def _test():

View file

@ -11,10 +11,11 @@ from evennia.utils.test_resources import EvenniaTest
try:
# this is a special optimized Django version, only available in current Django devel
from django.utils.unittest import TestCase
from django.utils.unittest import TestCase, override_settings
except ImportError:
from django.test import TestCase
from django.test import TestCase, override_settings
from evennia import settings_default
from evennia.locks import lockfuncs
# ------------------------------------------------------------
@ -25,7 +26,8 @@ from evennia.locks import lockfuncs
class TestLockCheck(EvenniaTest):
def testrun(self):
dbref = self.obj2.dbref
self.obj1.locks.add("owner:dbref(%s);edit:dbref(%s) or perm(Admin);examine:perm(Builder) and id(%s);delete:perm(Admin);get:all()" % (dbref, dbref, dbref))
self.obj1.locks.add("owner:dbref(%s);edit:dbref(%s) or perm(Admin);examine:perm(Builder) "
"and id(%s);delete:perm(Admin);get:all()" % (dbref, dbref, dbref))
self.obj2.permissions.add('Admin')
self.assertEqual(True, self.obj1.locks.check(self.obj2, 'owner'))
self.assertEqual(True, self.obj1.locks.check(self.obj2, 'edit'))
@ -36,20 +38,152 @@ class TestLockCheck(EvenniaTest):
self.assertEqual(False, self.obj1.locks.check(self.obj2, 'get'))
self.assertEqual(True, self.obj1.locks.check(self.obj2, 'not_exist', default=True))
class TestLockfuncs(EvenniaTest):
def testrun(self):
def setUp(self):
super(TestLockfuncs, self).setUp()
self.account2.permissions.add('Admin')
self.char2.permissions.add('Builder')
def test_booleans(self):
self.assertEquals(True, lockfuncs.true(self.account2, self.obj1))
self.assertEquals(True, lockfuncs.all(self.account2, self.obj1))
self.assertEquals(False, lockfuncs.false(self.account2, self.obj1))
self.assertEquals(False, lockfuncs.none(self.account2, self.obj1))
self.assertEquals(True, lockfuncs.self(self.obj1, self.obj1))
self.assertEquals(True, lockfuncs.self(self.account, self.account))
self.assertEquals(False, lockfuncs.superuser(self.account, None))
@override_settings(PERMISSION_HIERARCHY=settings_default.PERMISSION_HIERARCHY)
def test_account_perm(self):
self.assertEquals(False, lockfuncs.perm(self.account2, None, 'foo'))
self.assertEquals(False, lockfuncs.perm(self.account2, None, 'Developer'))
self.assertEquals(False, lockfuncs.perm(self.account2, None, 'Developers'))
self.assertEquals(True, lockfuncs.perm(self.account2, None, 'Admin'))
self.assertEquals(True, lockfuncs.perm(self.account2, None, 'Admins'))
self.assertEquals(True, lockfuncs.perm(self.account2, None, 'Player'))
self.assertEquals(True, lockfuncs.perm(self.account2, None, 'Players'))
self.assertEquals(True, lockfuncs.perm(self.account2, None, 'Builder'))
self.assertEquals(True, lockfuncs.perm(self.account2, None, 'Builders'))
self.assertEquals(True, lockfuncs.perm_above(self.account2, None, 'Builder'))
@override_settings(PERMISSION_HIERARCHY=settings_default.PERMISSION_HIERARCHY)
def test_puppet_perm(self):
self.assertEquals(False, lockfuncs.perm(self.char2, None, 'foo'))
self.assertEquals(False, lockfuncs.perm(self.char2, None, 'Developer'))
self.assertEquals(False, lockfuncs.perm(self.char2, None, 'Develoeprs'))
self.assertEquals(True, lockfuncs.perm(self.char2, None, 'Admin'))
self.assertEquals(True, lockfuncs.perm(self.char2, None, 'Admins'))
self.assertEquals(True, lockfuncs.perm(self.char2, None, 'Player'))
self.assertEquals(True, lockfuncs.perm(self.char2, None, 'Players'))
self.assertEquals(True, lockfuncs.perm(self.char2, None, 'Builder'))
self.assertEquals(True, lockfuncs.perm(self.char2, None, 'Builders'))
@override_settings(PERMISSION_HIERARCHY=settings_default.PERMISSION_HIERARCHY)
def test_account_perm_above(self):
self.assertEquals(True, lockfuncs.perm_above(self.char2, None, 'Builder'))
self.assertEquals(True, lockfuncs.perm_above(self.char2, None, 'Builders'))
self.assertEquals(True, lockfuncs.perm_above(self.char2, None, 'Player'))
self.assertEquals(False, lockfuncs.perm_above(self.char2, None, 'Admin'))
self.assertEquals(False, lockfuncs.perm_above(self.char2, None, 'Admins'))
self.assertEquals(False, lockfuncs.perm_above(self.char2, None, 'Developers'))
@override_settings(PERMISSION_HIERARCHY=settings_default.PERMISSION_HIERARCHY)
def test_quell_perm(self):
self.account2.db._quell = True
self.assertEquals(False, lockfuncs.false(self.char2, None))
self.assertEquals(False, lockfuncs.perm(self.char2, None, 'Developer'))
self.assertEquals(False, lockfuncs.perm(self.char2, None, 'Developers'))
self.assertEquals(False, lockfuncs.perm(self.char2, None, 'Admin'))
self.assertEquals(False, lockfuncs.perm(self.char2, None, 'Admins'))
self.assertEquals(True, lockfuncs.perm(self.char2, None, 'Player'))
self.assertEquals(True, lockfuncs.perm(self.char2, None, 'Players'))
self.assertEquals(True, lockfuncs.perm(self.char2, None, 'Builder'))
self.assertEquals(True, lockfuncs.perm(self.char2, None, 'Builders'))
@override_settings(PERMISSION_HIERARCHY=settings_default.PERMISSION_HIERARCHY)
def test_quell_above_perm(self):
self.assertEquals(True, lockfuncs.perm_above(self.char2, None, 'Player'))
self.assertEquals(True, lockfuncs.perm_above(self.char2, None, 'Builder'))
@override_settings(PERMISSION_HIERARCHY=settings_default.PERMISSION_HIERARCHY)
def test_object_perm(self):
self.obj2.permissions.add('Admin')
self.assertEqual(True, lockfuncs.true(self.obj2, self.obj1))
self.assertEqual(False, lockfuncs.false(self.obj2, self.obj1))
self.assertEqual(True, lockfuncs.perm(self.obj2, self.obj1, 'Admin'))
self.assertEqual(True, lockfuncs.perm_above(self.obj2, self.obj1, 'Builder'))
self.assertEquals(False, lockfuncs.perm(self.obj2, None, 'Developer'))
self.assertEquals(False, lockfuncs.perm(self.obj2, None, 'Developers'))
self.assertEquals(True, lockfuncs.perm(self.obj2, None, 'Admin'))
self.assertEquals(True, lockfuncs.perm(self.obj2, None, 'Admins'))
self.assertEquals(True, lockfuncs.perm(self.obj2, None, 'Player'))
self.assertEquals(True, lockfuncs.perm(self.obj2, None, 'Players'))
self.assertEquals(True, lockfuncs.perm(self.obj2, None, 'Builder'))
self.assertEquals(True, lockfuncs.perm(self.obj2, None, 'Builders'))
@override_settings(PERMISSION_HIERARCHY=settings_default.PERMISSION_HIERARCHY)
def test_object_above_perm(self):
self.obj2.permissions.add('Admin')
self.assertEquals(False, lockfuncs.perm_above(self.obj2, None, 'Admins'))
self.assertEquals(True, lockfuncs.perm_above(self.obj2, None, 'Builder'))
self.assertEquals(True, lockfuncs.perm_above(self.obj2, None, 'Builders'))
@override_settings(PERMISSION_HIERARCHY=settings_default.PERMISSION_HIERARCHY)
def test_pperm(self):
self.obj2.permissions.add('Developer')
self.char2.permissions.add('Developer')
self.assertEquals(False, lockfuncs.pperm(self.obj2, None, 'Players'))
self.assertEquals(True, lockfuncs.pperm(self.char2, None, 'Players'))
self.assertEquals(True, lockfuncs.pperm(self.account, None, 'Admins'))
self.assertEquals(True, lockfuncs.pperm_above(self.account, None, 'Builders'))
self.assertEquals(False, lockfuncs.pperm_above(self.account2, None, 'Admins'))
self.assertEquals(True, lockfuncs.pperm_above(self.char2, None, 'Players'))
def test_dbref(self):
dbref = self.obj2.dbref
self.assertEqual(True, lockfuncs.dbref(self.obj2, self.obj1, '%s' % dbref))
self.assertEquals(True, lockfuncs.dbref(self.obj2, None, '%s' % dbref))
self.assertEquals(False, lockfuncs.id(self.obj2, None, '%s' % (dbref + '1')))
dbref = self.account2.dbref
self.assertEquals(True, lockfuncs.pdbref(self.account2, None, '%s' % dbref))
self.assertEquals(False, lockfuncs.pid(self.account2, None, '%s' % (dbref + '1')))
def test_attr(self):
self.obj2.db.testattr = 45
self.assertEqual(True, lockfuncs.attr(self.obj2, self.obj1, 'testattr', '45'))
self.assertEqual(False, lockfuncs.attr_gt(self.obj2, self.obj1, 'testattr', '45'))
self.assertEqual(True, lockfuncs.attr_ge(self.obj2, self.obj1, 'testattr', '45'))
self.assertEqual(False, lockfuncs.attr_lt(self.obj2, self.obj1, 'testattr', '45'))
self.assertEqual(True, lockfuncs.attr_le(self.obj2, self.obj1, 'testattr', '45'))
self.assertEqual(False, lockfuncs.attr_ne(self.obj2, self.obj1, 'testattr', '45'))
self.assertEquals(True, lockfuncs.attr(self.obj2, None, 'testattr', '45'))
self.assertEquals(False, lockfuncs.attr_gt(self.obj2, None, 'testattr', '45'))
self.assertEquals(True, lockfuncs.attr_ge(self.obj2, None, 'testattr', '45'))
self.assertEquals(False, lockfuncs.attr_lt(self.obj2, None, 'testattr', '45'))
self.assertEquals(True, lockfuncs.attr_le(self.obj2, None, 'testattr', '45'))
self.assertEquals(True, lockfuncs.objattr(None, self.obj2, 'testattr', '45'))
self.assertEquals(True, lockfuncs.objattr(None, self.obj2, 'testattr', '45'))
self.assertEquals(False, lockfuncs.objattr(None, self.obj2, 'testattr', '45', compare='lt'))
def test_locattr(self):
self.obj2.location.db.locattr = 'test'
self.assertEquals(True, lockfuncs.locattr(self.obj2, None, 'locattr', 'test'))
self.assertEquals(False, lockfuncs.locattr(self.obj2, None, 'fail', 'testfail'))
self.assertEquals(True, lockfuncs.objlocattr(None, self.obj2, 'locattr', 'test'))
def test_tag(self):
self.obj2.tags.add("test1")
self.obj2.tags.add("test2", "category1")
self.assertEquals(True, lockfuncs.tag(self.obj2, None, 'test1'))
self.assertEquals(True, lockfuncs.tag(self.obj2, None, 'test2', 'category1'))
self.assertEquals(False, lockfuncs.tag(self.obj2, None, 'test1', 'category1'))
self.assertEquals(False, lockfuncs.tag(self.obj2, None, 'test1', 'category2'))
self.assertEquals(True, lockfuncs.objtag(None, self.obj2, 'test2', 'category1'))
self.assertEquals(False, lockfuncs.objtag(None, self.obj2, 'test2'))
def test_inside_holds(self):
self.assertEquals(True, lockfuncs.inside(self.char1, self.room1))
self.assertEquals(False, lockfuncs.inside(self.char1, self.room2))
self.assertEquals(True, lockfuncs.holds(self.room1, self.char1))
self.assertEquals(False, lockfuncs.holds(self.room2, self.char1))
def test_has_account(self):
self.assertEquals(True, lockfuncs.has_account(self.char1, None))
self.assertEquals(False, lockfuncs.has_account(self.obj1, None))
@override_settings(IRC_ENABLED=True, TESTVAL=[1, 2, 3])
def test_serversetting(self):
self.assertEquals(True, lockfuncs.serversetting(None, None, 'IRC_ENABLED', 'True'))
self.assertEquals(True, lockfuncs.serversetting(None, None, 'TESTVAL', '[1, 2, 3]'))
self.assertEquals(False, lockfuncs.serversetting(None, None, 'TESTVAL', '[1, 2, 4]'))
self.assertEquals(False, lockfuncs.serversetting(None, None, 'TESTVAL', '123'))