mirror of
https://github.com/evennia/evennia.git
synced 2026-04-02 05:57:16 +02:00
Further cleanup of source; making class methods _private for clarity in the API.
This commit is contained in:
parent
fc156b5a54
commit
c8df141e89
18 changed files with 607 additions and 588 deletions
|
|
@ -3,13 +3,13 @@ This module provides a set of permission lock functions for use
|
|||
with Evennia's permissions system.
|
||||
|
||||
To call these locks, make sure this module is included in the
|
||||
settings tuple PERMISSION_FUNC_MODULES then define a lock on the form
|
||||
'<access_type>:func(args)' and add it to the object's lockhandler.
|
||||
Run the access() method of the handler to execute the lock check.
|
||||
settings tuple PERMISSION_FUNC_MODULES then define a lock on the form
|
||||
'<access_type>:func(args)' and add it to the object's lockhandler.
|
||||
Run the access() method of the handler to execute the lock check.
|
||||
|
||||
Note that accessing_obj and accessed_obj can be any object type
|
||||
with a lock variable/field, so be careful to not expect
|
||||
a certain object type.
|
||||
a certain object type.
|
||||
|
||||
|
||||
Appendix: MUX locks
|
||||
|
|
@ -22,7 +22,7 @@ available like the MUX ones. So many of these are not available in
|
|||
basic Evennia, but could all be implemented easily if needed for the
|
||||
individual game.
|
||||
|
||||
MUX Name: Affects: Effect:
|
||||
MUX Name: Affects: Effect:
|
||||
-------------------------------------------------------------------------------
|
||||
DefaultLock: Exits: controls who may traverse the exit to
|
||||
its destination.
|
||||
|
|
@ -34,43 +34,43 @@ DefaultLock: Exits: controls who may traverse the exit to
|
|||
Players/Things: controls who may GET the object.
|
||||
Evennia: "get:<lockfunc()"
|
||||
EnterLock: Players/Things: controls who may ENTER the object
|
||||
Evennia:
|
||||
Evennia:
|
||||
GetFromLock: All but Exits: controls who may gets things from a given
|
||||
location.
|
||||
Evennia:
|
||||
Evennia:
|
||||
GiveLock: Players/Things: controls who may give the object.
|
||||
Evennia:
|
||||
Evennia:
|
||||
LeaveLock: Players/Things: controls who may LEAVE the object.
|
||||
Evennia:
|
||||
Evennia:
|
||||
LinkLock: All but Exits: controls who may link to the location if the
|
||||
location is LINK_OK (for linking exits or
|
||||
setting drop-tos) or ABODE (for setting
|
||||
homes)
|
||||
Evennia:
|
||||
Evennia:
|
||||
MailLock: Players: controls who may @mail the player.
|
||||
Evennia:
|
||||
Evennia:
|
||||
OpenLock: All but Exits: controls who may open an exit.
|
||||
Evennia:
|
||||
Evennia:
|
||||
PageLock: Players: controls who may page the player.
|
||||
Evennia: "send:<lockfunc()>"
|
||||
ParentLock: All: controls who may make @parent links to the
|
||||
object.
|
||||
Evennia: Typeclasses and "puppet:<lockstring()>"
|
||||
ReceiveLock: Players/Things: controls who may give things to the object.
|
||||
Evennia:
|
||||
Evennia:
|
||||
SpeechLock: All but Exits: controls who may speak in that location
|
||||
Evennia:
|
||||
Evennia:
|
||||
TeloutLock: All but Exits: controls who may teleport out of the
|
||||
location.
|
||||
Evennia:
|
||||
Evennia:
|
||||
TportLock: Rooms/Things: controls who may teleport there
|
||||
Evennia:
|
||||
Evennia:
|
||||
UseLock: All but Exits: controls who may USE the object, GIVE the
|
||||
object money and have the PAY attributes
|
||||
run, have their messages heard and possibly
|
||||
acted on by LISTEN and AxHEAR, and invoke
|
||||
$-commands stored on the object.
|
||||
Evennia: Commands and Cmdsets.
|
||||
Evennia: Commands and Cmdsets.
|
||||
DropLock: All but rooms: controls who may drop that object.
|
||||
Evennia:
|
||||
VisibleLock: All: Controls object visibility when the object
|
||||
|
|
@ -85,7 +85,7 @@ from django.conf import settings
|
|||
from src.utils import search
|
||||
from src.utils import utils
|
||||
|
||||
PERMISSION_HIERARCHY = [p.lower() for p in settings.PERMISSION_HIERARCHY]
|
||||
_PERMISSION_HIERARCHY = [p.lower() for p in settings.PERMISSION_HIERARCHY]
|
||||
|
||||
def _to_player(accessing_obj):
|
||||
"Helper function. Makes sure an accessing object is a player object"
|
||||
|
|
@ -95,85 +95,85 @@ def _to_player(accessing_obj):
|
|||
return accessing_obj
|
||||
|
||||
|
||||
# lock functions
|
||||
# lock functions
|
||||
|
||||
def true(*args, **kwargs):
|
||||
"Always returns True."
|
||||
return True
|
||||
def all(*args, **kwargs):
|
||||
return True
|
||||
return True
|
||||
def false(*args, **kwargs):
|
||||
"Always returns False"
|
||||
return False
|
||||
return False
|
||||
def none(*args, **kwargs):
|
||||
return False
|
||||
return False
|
||||
|
||||
def perm(accessing_obj, accessed_obj, *args, **kwargs):
|
||||
"""
|
||||
The basic permission-checker. Ignores case.
|
||||
The basic permission-checker. Ignores case.
|
||||
|
||||
Usage:
|
||||
Usage:
|
||||
perm(<permission>)
|
||||
|
||||
|
||||
where <permission> is the permission accessing_obj must
|
||||
have in order to pass the lock. If the given permission
|
||||
is part of PERMISSION_HIERARCHY, permission is also granted
|
||||
to all ranks higher up in the hierarchy.
|
||||
have in order to pass the lock. If the given permission
|
||||
is part of _PERMISSION_HIERARCHY, permission is also granted
|
||||
to all ranks higher up in the hierarchy.
|
||||
"""
|
||||
try:
|
||||
perm = args[0].lower()
|
||||
permissions = [p.lower() for p in accessing_obj.permissions]
|
||||
except AttributeError, IndexError:
|
||||
return False
|
||||
|
||||
return False
|
||||
|
||||
if perm in permissions:
|
||||
# simplest case - we have a direct match
|
||||
return True
|
||||
if perm in PERMISSION_HIERARCHY:
|
||||
return True
|
||||
if perm in _PERMISSION_HIERARCHY:
|
||||
# check if we have a higher hierarchy position
|
||||
ppos = PERMISSION_HIERARCHY.index(perm)
|
||||
return any(1 for hpos, hperm in enumerate(PERMISSION_HIERARCHY)
|
||||
ppos = _PERMISSION_HIERARCHY.index(perm)
|
||||
return any(1 for hpos, hperm in enumerate(_PERMISSION_HIERARCHY)
|
||||
if hperm in permissions and hpos > ppos)
|
||||
return False
|
||||
return False
|
||||
|
||||
def perm_above(accessing_obj, accessed_obj, *args, **kwargs):
|
||||
"""
|
||||
Only allow objects with a permission *higher* in the permission
|
||||
hierarchy than the one given. If there is no such higher rank,
|
||||
hierarchy than the one given. If there is no such higher rank,
|
||||
it's assumed we refer to superuser. If no hierarchy is defined,
|
||||
this function has no meaning and returns False.
|
||||
this function has no meaning and returns False.
|
||||
"""
|
||||
try:
|
||||
perm = args[0].lower()
|
||||
except IndexError:
|
||||
return False
|
||||
return False
|
||||
|
||||
if perm in PERMISSION_HIERARCHY:
|
||||
ppos = PERMISSION_HIERARCHY.index(perm)
|
||||
return any(1 for hpos, hperm in enumerate(PERMISSION_HIERARCHY)
|
||||
if perm in _PERMISSION_HIERARCHY:
|
||||
ppos = _PERMISSION_HIERARCHY.index(perm)
|
||||
return any(1 for hpos, hperm in enumerate(_PERMISSION_HIERARCHY)
|
||||
if hperm in [p.lower() for p in accessing_obj.permissions] and hpos > ppos)
|
||||
return False
|
||||
return False
|
||||
|
||||
def pperm(accessing_obj, accessed_obj, *args, **kwargs):
|
||||
"""
|
||||
The basic permission-checker for Player objects. Ignores case.
|
||||
The basic permission-checker for Player objects. Ignores case.
|
||||
|
||||
Usage:
|
||||
Usage:
|
||||
pperm(<permission>)
|
||||
|
||||
|
||||
where <permission> is the permission accessing_obj must
|
||||
have in order to pass the lock. If the given permission
|
||||
is part of PERMISSION_HIERARCHY, permission is also granted
|
||||
to all ranks higher up in the hierarchy.
|
||||
have in order to pass the lock. If the given permission
|
||||
is part of _PERMISSION_HIERARCHY, permission is also granted
|
||||
to all ranks higher up in the hierarchy.
|
||||
"""
|
||||
return perm(_to_player(accessing_obj), accessed_obj, *args, **kwargs)
|
||||
|
||||
def pperm_above(accessing_obj, accessed_obj, *args, **kwargs):
|
||||
"""
|
||||
Only allow Player objects with a permission *higher* in the permission
|
||||
hierarchy than the one given. If there is no such higher rank,
|
||||
hierarchy than the one given. If there is no such higher rank,
|
||||
it's assumed we refer to superuser. If no hierarchy is defined,
|
||||
this function has no meaning and returns False.
|
||||
this function has no meaning and returns False.
|
||||
"""
|
||||
return perm_above(_to_player(accessing_obj), accessed_obj, *args, **kwargs)
|
||||
|
||||
|
|
@ -181,7 +181,7 @@ def dbref(accessing_obj, accessed_obj, *args, **kwargs):
|
|||
"""
|
||||
Usage:
|
||||
dbref(3)
|
||||
|
||||
|
||||
This lock type checks if the checking object
|
||||
has a particular dbref. Note that this only
|
||||
works for checking objects that are stored
|
||||
|
|
@ -195,7 +195,7 @@ def dbref(accessing_obj, accessed_obj, *args, **kwargs):
|
|||
return False
|
||||
if hasattr(accessing_obj, 'id'):
|
||||
return dbref == accessing_obj.id
|
||||
return False
|
||||
return False
|
||||
|
||||
def pdbref(accessing_obj, accessed_obj, *args, **kwargs):
|
||||
"""
|
||||
|
|
@ -212,7 +212,7 @@ def pid(accessing_obj, accessed_obj, *args, **kwargs):
|
|||
return dbref(_to_player(accessing_obj), accessed_obj, *args, **kwargs)
|
||||
|
||||
|
||||
# this is more efficient than multiple if ... elif statments
|
||||
# this is more efficient than multiple if ... elif statments
|
||||
CF_MAPPING = {'eq': lambda val1, val2: val1 == val2 or int(val1) == int(val2),
|
||||
'gt': lambda val1, val2: int(val1) > int(val2),
|
||||
'lt': lambda val1, val2: int(val1) < int(val2),
|
||||
|
|
@ -232,7 +232,7 @@ def attr(accessing_obj, accessed_obj, *args, **kwargs):
|
|||
how the value should be compared with one on accessing_obj (so
|
||||
compare=gt means the accessing_obj must have a value greater than
|
||||
the one given).
|
||||
|
||||
|
||||
Searches attributes *and* properties stored on the checking
|
||||
object. The first form works like a flag - if the
|
||||
attribute/property exists on the object, the value is checked for
|
||||
|
|
@ -240,17 +240,17 @@ def attr(accessing_obj, accessed_obj, *args, **kwargs):
|
|||
attribute/property matches. Note that all retrieved values will be
|
||||
converted to strings before doing the comparison.
|
||||
"""
|
||||
# deal with arguments
|
||||
# deal with arguments
|
||||
if not args:
|
||||
return False
|
||||
attrname = args[0].strip()
|
||||
value = None
|
||||
value = None
|
||||
if len(args) > 1:
|
||||
value = args[1].strip()
|
||||
compare = 'eq'
|
||||
if kwargs:
|
||||
compare = kwargs.get('compare', 'eq')
|
||||
|
||||
|
||||
def valcompare(val1, val2, typ='eq'):
|
||||
"compare based on type"
|
||||
try:
|
||||
|
|
@ -258,20 +258,20 @@ def attr(accessing_obj, accessed_obj, *args, **kwargs):
|
|||
except Exception, e:
|
||||
#print e
|
||||
# this might happen if we try to compare two things that cannot be compared
|
||||
return False
|
||||
return False
|
||||
|
||||
# first, look for normal properties on the object trying to gain access
|
||||
# first, look for normal properties on the object trying to gain access
|
||||
if hasattr(accessing_obj, attrname):
|
||||
if value:
|
||||
return valcompare(str(getattr(accessing_obj, attrname)), value, compare)
|
||||
return valcompare(str(getattr(accessing_obj, attrname)), value, compare)
|
||||
return bool(getattr(accessing_obj, attrname)) # will return Fail on False value etc
|
||||
# check attributes, if they exist
|
||||
# check attributes, if they exist
|
||||
if (hasattr(accessing_obj, 'has_attribute') and accessing_obj.has_attribute(attrname)):
|
||||
if value:
|
||||
return (hasattr(accessing_obj, 'get_attribute')
|
||||
return (hasattr(accessing_obj, 'get_attribute')
|
||||
and valcompare(accessing_obj.get_attribute(attrname), value, compare))
|
||||
return bool(accessing_obj.get_attribute(attrname)) # fails on False/None values
|
||||
return False
|
||||
return False
|
||||
|
||||
def objattr(accessing_obj, accessed_obj, *args, **kwargs):
|
||||
"""
|
||||
|
|
@ -280,7 +280,7 @@ def objattr(accessing_obj, accessed_obj, *args, **kwargs):
|
|||
objattr(attrname, value)
|
||||
objattr(attrname, value, compare=type)
|
||||
|
||||
Works like attr, except it looks for an attribute on
|
||||
Works like attr, except it looks for an attribute on
|
||||
accessing_obj.obj, if such an entity exists. Suitable
|
||||
for commands.
|
||||
|
||||
|
|
@ -295,8 +295,8 @@ def locattr(accessing_obj, accessed_obj, *args, **kwargs):
|
|||
locattr(attrname, value)
|
||||
locattr(attrname, value, compare=type)
|
||||
|
||||
Works like attr, except it looks for an attribute on
|
||||
accessing_obj.location, if such an entity exists.
|
||||
Works like attr, except it looks for an attribute on
|
||||
accessing_obj.location, if such an entity exists.
|
||||
|
||||
"""
|
||||
if hasattr(accessing_obj, "location"):
|
||||
|
|
@ -305,14 +305,14 @@ def locattr(accessing_obj, accessed_obj, *args, **kwargs):
|
|||
|
||||
def attr_eq(accessing_obj, accessed_obj, *args, **kwargs):
|
||||
"""
|
||||
Usage:
|
||||
Usage:
|
||||
attr_gt(attrname, 54)
|
||||
"""
|
||||
return attr(accessing_obj, accessed_obj, *args, **kwargs)
|
||||
|
||||
def attr_gt(accessing_obj, accessed_obj, *args, **kwargs):
|
||||
"""
|
||||
Usage:
|
||||
Usage:
|
||||
attr_gt(attrname, 54)
|
||||
|
||||
Only true if access_obj's attribute > the value given.
|
||||
|
|
@ -320,7 +320,7 @@ def attr_gt(accessing_obj, accessed_obj, *args, **kwargs):
|
|||
return attr(accessing_obj, accessed_obj, *args, **{'compare':'gt'})
|
||||
def attr_ge(accessing_obj, accessed_obj, *args, **kwargs):
|
||||
"""
|
||||
Usage:
|
||||
Usage:
|
||||
attr_gt(attrname, 54)
|
||||
|
||||
Only true if access_obj's attribute >= the value given.
|
||||
|
|
@ -328,7 +328,7 @@ def attr_ge(accessing_obj, accessed_obj, *args, **kwargs):
|
|||
return attr(accessing_obj, accessed_obj, *args, **{'compare':'ge'})
|
||||
def attr_lt(accessing_obj, accessed_obj, *args, **kwargs):
|
||||
"""
|
||||
Usage:
|
||||
Usage:
|
||||
attr_gt(attrname, 54)
|
||||
|
||||
Only true if access_obj's attribute < the value given.
|
||||
|
|
@ -336,7 +336,7 @@ def attr_lt(accessing_obj, accessed_obj, *args, **kwargs):
|
|||
return attr(accessing_obj, accessed_obj, *args, **{'compare':'lt'})
|
||||
def attr_le(accessing_obj, accessed_obj, *args, **kwargs):
|
||||
"""
|
||||
Usage:
|
||||
Usage:
|
||||
attr_gt(attrname, 54)
|
||||
|
||||
Only true if access_obj's attribute <= the value given.
|
||||
|
|
@ -344,7 +344,7 @@ def attr_le(accessing_obj, accessed_obj, *args, **kwargs):
|
|||
return attr(accessing_obj, accessed_obj, *args, **{'compare':'le'})
|
||||
def attr_ne(accessing_obj, accessed_obj, *args, **kwargs):
|
||||
"""
|
||||
Usage:
|
||||
Usage:
|
||||
attr_gt(attrname, 54)
|
||||
|
||||
Only true if access_obj's attribute != the value given.
|
||||
|
|
@ -353,7 +353,7 @@ def attr_ne(accessing_obj, accessed_obj, *args, **kwargs):
|
|||
|
||||
def holds(accessing_obj, accessed_obj, *args, **kwargs):
|
||||
"""
|
||||
Usage:
|
||||
Usage:
|
||||
holds() # checks if accessed_obj or accessed_obj.obj is held by accessing_obj
|
||||
holds(key/dbref) # checks if accessing_obj holds an object with given key/dbref
|
||||
|
||||
|
|
@ -364,50 +364,50 @@ def holds(accessing_obj, accessed_obj, *args, **kwargs):
|
|||
try:
|
||||
# commands and scripts don't have contents, so we are usually looking
|
||||
# for the contents of their .obj property instead (i.e. the object the
|
||||
# command/script is attached to).
|
||||
# command/script is attached to).
|
||||
contents = accessing_obj.contents
|
||||
except AttributeError:
|
||||
try:
|
||||
try:
|
||||
contents = accessing_obj.obj.contents
|
||||
except AttributeError:
|
||||
return False
|
||||
return False
|
||||
|
||||
def check_holds(objid):
|
||||
# helper function. Compares both dbrefs and keys/aliases.
|
||||
objid = str(objid)
|
||||
dbref = utils.dbref(objid)
|
||||
dbref = utils.dbref(objid)
|
||||
if dbref and any((True for obj in contents if obj.id == dbref)):
|
||||
return True
|
||||
return True
|
||||
objid = objid.lower()
|
||||
return any((True for obj in contents
|
||||
return any((True for obj in contents
|
||||
if obj.key.lower() == objid or objid in [al.lower() for al in obj.aliases]))
|
||||
|
||||
if args and args[0]:
|
||||
return check_holds(args[0])
|
||||
else:
|
||||
else:
|
||||
try:
|
||||
if check_holds(accessed_obj.id):
|
||||
#print "holds: accessed_obj.id - True"
|
||||
return True
|
||||
except Exception:
|
||||
pass
|
||||
pass
|
||||
#print "holds: accessed_obj.obj.id -", hasattr(accessed_obj, "obj") and check_holds(accessed_obj.obj.id)
|
||||
return hasattr(accessed_obj, "obj") and check_holds(accessed_obj.obj.id)
|
||||
|
||||
|
||||
def superuser(*args, **kwargs):
|
||||
"""
|
||||
Only accepts an accesing_obj that is superuser (e.g. user #1)
|
||||
|
||||
|
||||
Since a superuser would not ever reach this check (superusers
|
||||
bypass the lock entirely), any user who gets this far cannot be a
|
||||
superuser, hence we just return False. :)
|
||||
"""
|
||||
return False
|
||||
|
||||
return False
|
||||
|
||||
def serversetting(accessing_obj, accessed_obj, *args, **kwargs):
|
||||
"""
|
||||
Only returns true if the Evennia settings exists, alternatively has a certain value.
|
||||
|
||||
|
||||
Usage:
|
||||
serversetting(IRC_ENABLED)
|
||||
serversetting(BASE_SCRIPT_PATH, [game.gamesrc.scripts])
|
||||
|
|
@ -418,16 +418,16 @@ def serversetting(accessing_obj, accessed_obj, *args, **kwargs):
|
|||
return False
|
||||
if len(args) < 2:
|
||||
setting = args[0]
|
||||
val = "True"
|
||||
val = "True"
|
||||
else:
|
||||
setting, val = args[0], args[1]
|
||||
# convert
|
||||
if val == 'True':
|
||||
val = True
|
||||
elif val == 'False':
|
||||
val = False
|
||||
val = False
|
||||
elif val.isdigit():
|
||||
val = int(val)
|
||||
if setting in settings._wrapped.__dict__:
|
||||
return settings._wrapped.__dict__[setting] == val
|
||||
return False
|
||||
return False
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue