Big commit. We now have a respectable command table with built in permission checking. I've commented this pretty well, so see cmdtable.py and cmdhandler.py for more details. There is also some assorted cleanup and an unrelated fix or two resulting from the new Twisted back-end. Note that for the permissions, you will eventually be able to override the codebase's permissions via the web interface for each command.
This commit is contained in:
parent
9746382614
commit
204ef6d4c5
7 changed files with 151 additions and 69 deletions
|
|
@ -9,17 +9,15 @@ class GenericPerm(models.Model):
|
|||
permissions = (
|
||||
("announce", "May use @wall to make announcements"),
|
||||
("boot", "May use @boot to kick players"),
|
||||
("builder", "May build"),
|
||||
("builder", "Can build and modify objects"),
|
||||
("chown_all", "Can @chown anything to anyone."),
|
||||
("control_all", "May control everything"),
|
||||
("examine_all", "Can examine any object"),
|
||||
("extended_who", "May see extended WHO list"),
|
||||
("free_money", "Has infinite money"),
|
||||
("long_fingers", "May get/look/examine etc. from a distance"),
|
||||
("steal", "May give negative money"),
|
||||
("set_hide", "May set themself invisible"),
|
||||
("shutdown", "May @shutdown the site"),
|
||||
("tel_anywhere", "May @teleport anywhere"),
|
||||
("tel_anyone", "May @teleport anything"),
|
||||
("see_session_data", "May see detailed player session data"),
|
||||
("process_control", "May shutdown/restart/reload the game"),
|
||||
("manage_players", "Can change passwords, siteban, etc."),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -133,6 +133,8 @@ class Object(models.Model):
|
|||
"""
|
||||
Checks to see whether a user has the specified permission or is a super
|
||||
user.
|
||||
|
||||
perm: (string) A string representing the desired permission.
|
||||
"""
|
||||
if not self.is_player():
|
||||
return False
|
||||
|
|
@ -145,6 +147,28 @@ class Object(models.Model):
|
|||
else:
|
||||
return False
|
||||
|
||||
def user_has_perm_list(self, perm_list):
|
||||
"""
|
||||
Checks to see whether a user has the specified permission or is a super
|
||||
user. This form accepts an iterable of strings representing permissions,
|
||||
if the user has any of them return true.
|
||||
|
||||
perm: (iterable) An iterable of strings of permissions.
|
||||
"""
|
||||
if not self.is_player():
|
||||
return False
|
||||
|
||||
if self.is_superuser():
|
||||
return True
|
||||
|
||||
for perm in perm_list:
|
||||
# Stop searching perms on the first match.
|
||||
if self.get_user_account().has_perm(perm):
|
||||
return True
|
||||
|
||||
# Fall through to failure
|
||||
return False
|
||||
|
||||
def owns_other(self, other_obj):
|
||||
"""
|
||||
See if the envoked object owns another object.
|
||||
|
|
@ -170,10 +194,9 @@ class Object(models.Model):
|
|||
if self.owns_other(other_obj):
|
||||
# If said object owns the target, then give it the green.
|
||||
return True
|
||||
else:
|
||||
# Still pending more stuff here, for now assume we have
|
||||
# dominance. Bad assumption.
|
||||
return True
|
||||
|
||||
# They've failed to meet any of the above conditions.
|
||||
return False
|
||||
|
||||
def set_home(self, new_home):
|
||||
"""
|
||||
|
|
@ -643,6 +666,9 @@ class CommChannel(models.Model):
|
|||
|
||||
class Meta:
|
||||
ordering = ['-name']
|
||||
permissions = (
|
||||
("emit_commchannel", "May @cemit over channels."),
|
||||
)
|
||||
|
||||
class Admin:
|
||||
list_display = ('name', 'owner')
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
from traceback import format_exc
|
||||
import time
|
||||
|
||||
import defines_global
|
||||
import commands_privileged
|
||||
import commands_general
|
||||
import commands_comsys
|
||||
|
|
@ -60,6 +62,9 @@ def handle(cdat):
|
|||
alias_list = server.cmd_alias_list
|
||||
parsed_input['root_cmd'] = alias_list.get(parsed_input['root_cmd'],parsed_input['root_cmd'])
|
||||
|
||||
# This will hold the reference to the command's function.
|
||||
cmd = None
|
||||
|
||||
if session.logged_in:
|
||||
# Store the timestamp of the user's last command.
|
||||
session.cmd_last = time.time()
|
||||
|
|
@ -99,15 +104,28 @@ def handle(cdat):
|
|||
parsed_input['root_cmd'] = '@cemit'
|
||||
|
||||
# Get the command's function reference (Or False)
|
||||
cmd = cmdtable.return_cfunc(parsed_input['root_cmd'])
|
||||
cmdtuple = cmdtable.return_cmdtuple(parsed_input['root_cmd'])
|
||||
if cmdtuple:
|
||||
# If there is a permissions element to the entry, check perms.
|
||||
if cmdtuple[1]:
|
||||
if not session.get_pobject().user_has_perm_list(cmdtuple[1]):
|
||||
session.msg(defines_global.NOPERMS_MSG)
|
||||
return
|
||||
# If flow reaches this point, user has perms and command is ready.
|
||||
cmd = cmdtuple[0]
|
||||
|
||||
else:
|
||||
# Not logged in, look through the unlogged-in command table.
|
||||
cmd = cmdtable.return_cfunc(parsed_input['root_cmd'], unlogged_cmd=True)
|
||||
cmdtuple = cmdtable.return_cmdtuple(parsed_input['root_cmd'], unlogged_cmd=True)
|
||||
if cmdtuple:
|
||||
cmd = cmdtuple[0]
|
||||
|
||||
# Debugging stuff.
|
||||
#session.msg("ROOT : %s" % (parsed_input['root_cmd'],))
|
||||
#session.msg("SPLIT: %s" % (parsed_input['splitted'],))
|
||||
|
||||
if not cmd:
|
||||
raise UnknownCommand
|
||||
|
||||
if callable(cmd):
|
||||
cdat['uinput'] = parsed_input
|
||||
try:
|
||||
|
|
|
|||
112
cmdtable.py
112
cmdtable.py
|
|
@ -3,65 +3,79 @@ import commands_general
|
|||
import commands_privileged
|
||||
import commands_comsys
|
||||
|
||||
"""
|
||||
Command Table Entries
|
||||
---------------------
|
||||
Each command entry consists of a key and a tuple containing a reference to the
|
||||
command's function, and a tuple of the permissions to match against. The user
|
||||
only need have one of the permissions in the permissions tuple to gain
|
||||
access to the command. Obviously, super users don't have to worry about this
|
||||
stuff. If the command is open to all (or you want to implement your own
|
||||
privilege checking in the command function), use None in place of the
|
||||
permissions tuple.
|
||||
"""
|
||||
|
||||
# Unlogged-in Command Table
|
||||
uncon_ctable = {
|
||||
"connect": commands_unloggedin.cmd_connect,
|
||||
"create": commands_unloggedin.cmd_create,
|
||||
"quit": commands_unloggedin.cmd_quit,
|
||||
"connect": (commands_unloggedin.cmd_connect, None),
|
||||
"create": (commands_unloggedin.cmd_create, None),
|
||||
"quit": (commands_unloggedin.cmd_quit, None),
|
||||
}
|
||||
|
||||
|
||||
# Command Table
|
||||
ctable = {
|
||||
"addcom": commands_comsys.cmd_addcom,
|
||||
"comlist": commands_comsys.cmd_comlist,
|
||||
"delcom": commands_comsys.cmd_delcom,
|
||||
"drop": commands_general.cmd_drop,
|
||||
"examine": commands_general.cmd_examine,
|
||||
"get": commands_general.cmd_get,
|
||||
"help": commands_general.cmd_help,
|
||||
"idle": commands_general.cmd_idle,
|
||||
"inventory": commands_general.cmd_inventory,
|
||||
"look": commands_general.cmd_look,
|
||||
"page": commands_general.cmd_page,
|
||||
"pose": commands_general.cmd_pose,
|
||||
"quit": commands_general.cmd_quit,
|
||||
"say": commands_general.cmd_say,
|
||||
"time": commands_general.cmd_time,
|
||||
"uptime": commands_general.cmd_uptime,
|
||||
"version": commands_general.cmd_version,
|
||||
"who": commands_general.cmd_who,
|
||||
"@ccreate": commands_comsys.cmd_ccreate,
|
||||
"@cdestroy": commands_comsys.cmd_cdestroy,
|
||||
"@cemit": commands_comsys.cmd_cemit,
|
||||
"@clist": commands_comsys.cmd_clist,
|
||||
"@create": commands_privileged.cmd_create,
|
||||
"@description": commands_privileged.cmd_description,
|
||||
"@destroy": commands_privileged.cmd_destroy,
|
||||
"@dig": commands_privileged.cmd_dig,
|
||||
"@emit": commands_privileged.cmd_emit,
|
||||
"@find": commands_privileged.cmd_find,
|
||||
"@link": commands_privileged.cmd_link,
|
||||
"@list": commands_privileged.cmd_list,
|
||||
"@name": commands_privileged.cmd_name,
|
||||
"@nextfree": commands_privileged.cmd_nextfree,
|
||||
"@newpassword": commands_privileged.cmd_newpassword,
|
||||
"@open": commands_privileged.cmd_open,
|
||||
"@password": commands_privileged.cmd_password,
|
||||
"@reload": commands_privileged.cmd_reload,
|
||||
"@set": commands_privileged.cmd_set,
|
||||
"@shutdown": commands_privileged.cmd_shutdown,
|
||||
"@teleport": commands_privileged.cmd_teleport,
|
||||
"@unlink": commands_privileged.cmd_unlink,
|
||||
"@wall": commands_privileged.cmd_wall,
|
||||
|
||||
"addcom": (commands_comsys.cmd_addcom, None),
|
||||
"comlist": (commands_comsys.cmd_comlist, None),
|
||||
"delcom": (commands_comsys.cmd_delcom, None),
|
||||
"drop": (commands_general.cmd_drop, None),
|
||||
"examine": (commands_general.cmd_examine, None),
|
||||
"get": (commands_general.cmd_get, None),
|
||||
"help": (commands_general.cmd_help, None),
|
||||
"idle": (commands_general.cmd_idle, None),
|
||||
"inventory": (commands_general.cmd_inventory, None),
|
||||
"look": (commands_general.cmd_look, None),
|
||||
"page": (commands_general.cmd_page, None),
|
||||
"pose": (commands_general.cmd_pose, None),
|
||||
"quit": (commands_general.cmd_quit, None),
|
||||
"say": (commands_general.cmd_say, None),
|
||||
"time": (commands_general.cmd_time, None),
|
||||
"uptime": (commands_general.cmd_uptime, None),
|
||||
"version": (commands_general.cmd_version, None),
|
||||
"who": (commands_general.cmd_who, None),
|
||||
"@ccreate": (commands_comsys.cmd_ccreate, ("objects.add_commchannel")),
|
||||
"@cdestroy": (commands_comsys.cmd_cdestroy, ("objects.delete_commchannel")),
|
||||
"@cemit": (commands_comsys.cmd_cemit, ("objects.emit_commchannel")),
|
||||
"@clist": (commands_comsys.cmd_clist, None),
|
||||
"@create": (commands_privileged.cmd_create, ("genperms.builder")),
|
||||
"@description": (commands_privileged.cmd_description, None),
|
||||
"@destroy": (commands_privileged.cmd_destroy, ("genperms.builder")),
|
||||
"@dig": (commands_privileged.cmd_dig, ("genperms.builder")),
|
||||
"@emit": (commands_privileged.cmd_emit, ("genperms.announce")),
|
||||
"@find": (commands_privileged.cmd_find, ("genperms.builder")),
|
||||
"@link": (commands_privileged.cmd_link, ("genperms.builder")),
|
||||
"@list": (commands_privileged.cmd_list, ("genperms.process_control")),
|
||||
"@name": (commands_privileged.cmd_name, None),
|
||||
"@nextfree": (commands_privileged.cmd_nextfree, ("genperms.builder")),
|
||||
"@newpassword": (commands_privileged.cmd_newpassword, ("genperms.manage_players")),
|
||||
"@open": (commands_privileged.cmd_open, ("genperms.builder")),
|
||||
"@password": (commands_privileged.cmd_password, None),
|
||||
"@reload": (commands_privileged.cmd_reload, ("genperms.process_control")),
|
||||
"@set": (commands_privileged.cmd_set, None),
|
||||
"@shutdown": (commands_privileged.cmd_shutdown, ("genperms.process_control")),
|
||||
"@teleport": (commands_privileged.cmd_teleport, ("genperms.builder")),
|
||||
"@unlink": (commands_privileged.cmd_unlink, ("genperms.builder")),
|
||||
"@wall": (commands_privileged.cmd_wall, ("genperms.announce")),
|
||||
}
|
||||
|
||||
def return_cfunc(func_name, unlogged_cmd=False):
|
||||
def return_cmdtuple(func_name, unlogged_cmd=False):
|
||||
"""
|
||||
Returns a reerence to the command's function. If there are no matches,
|
||||
Returns a reference to the command's tuple. If there are no matches,
|
||||
returns false.
|
||||
"""
|
||||
if not unlogged_cmd:
|
||||
return ctable.get(func_name, False)
|
||||
cfunc = ctable.get(func_name, False)
|
||||
else:
|
||||
return uncon_ctable.get(func_name, False)
|
||||
cfunc = uncon_ctable.get(func_name, False)
|
||||
|
||||
return cfunc
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
import os
|
||||
import resource
|
||||
|
||||
import defines_global
|
||||
from django.contrib.auth.models import User
|
||||
from apps.objects.models import Object
|
||||
import defines_global
|
||||
import cmdhandler
|
||||
import session_mgr
|
||||
import functions_general
|
||||
|
|
@ -132,8 +132,12 @@ def cmd_description(cdat):
|
|||
session.msg("I don't see that here.")
|
||||
return
|
||||
else:
|
||||
new_desc = '='.join(eq_args[1:])
|
||||
target_obj = results[0]
|
||||
if not pobject.controls_other(target):
|
||||
session.msg(defines_global.NOCONTROL_MSG)
|
||||
return
|
||||
|
||||
new_desc = '='.join(eq_args[1:])
|
||||
session.msg("%s - DESCRIPTION set." % (target_obj,))
|
||||
target_obj.set_description(new_desc)
|
||||
|
||||
|
|
@ -403,6 +407,10 @@ def cmd_link(cdat):
|
|||
|
||||
# We know we can get the first entry now.
|
||||
target = target[0]
|
||||
|
||||
if not pobject.controls_other(target):
|
||||
session.msg(defines_global.NOCONTROL_MSG)
|
||||
return
|
||||
|
||||
# If we do something like "@link blah=", we unlink the object.
|
||||
if len(dest_name) == 0:
|
||||
|
|
@ -451,6 +459,10 @@ def cmd_unlink(cdat):
|
|||
session.msg("I don't see that here.")
|
||||
return
|
||||
else:
|
||||
if not pobject.controls_other(results[0]):
|
||||
session.msg(defines_global.NOCONTROL_MSG)
|
||||
return
|
||||
|
||||
results[0].set_home(None)
|
||||
session.msg("You have unlinked %s." % (results[0],))
|
||||
|
||||
|
|
@ -558,6 +570,10 @@ def cmd_set(cdat):
|
|||
return
|
||||
|
||||
victim = victim[0]
|
||||
if not pobject.controls_other(victim):
|
||||
session.msg(defines_global.NOCONTROL_MSG)
|
||||
return
|
||||
|
||||
attrib_args = eq_args[1].split(':')
|
||||
|
||||
if len(attrib_args) > 1:
|
||||
|
|
@ -609,7 +625,9 @@ def cmd_find(cdat):
|
|||
session = cdat['session']
|
||||
server = cdat['server']
|
||||
searchstring = ' '.join(cdat['uinput']['splitted'][1:])
|
||||
|
||||
pobject = session.get_pobject()
|
||||
can_find = pobject.user_has_perm("genperms.builder")
|
||||
|
||||
if searchstring == '':
|
||||
session.msg("No search pattern given.")
|
||||
return
|
||||
|
|
@ -630,7 +648,8 @@ def cmd_wall(cdat):
|
|||
"""
|
||||
session = cdat['session']
|
||||
wallstring = ' '.join(cdat['uinput']['splitted'][1:])
|
||||
|
||||
pobject = session.get_pobject()
|
||||
|
||||
if wallstring == '':
|
||||
session.msg("Announce what?")
|
||||
return
|
||||
|
|
@ -644,7 +663,8 @@ def cmd_shutdown(cdat):
|
|||
"""
|
||||
session = cdat['session']
|
||||
server = cdat['server']
|
||||
|
||||
pobject = session.get_pobject()
|
||||
|
||||
session.msg('Shutting down...')
|
||||
print 'Server shutdown by %s(#%d)' % (session.get_pobject().get_name(), session.get_pobject().id,)
|
||||
print 'Server shutdown by %s' % (pobject.get_name(show_dbref=False),)
|
||||
server.shutdown()
|
||||
|
|
|
|||
|
|
@ -34,3 +34,9 @@ NOSET_ATTRIBS = ["MONEY", "ALIAS", "LASTPAGED", "CHANLIST", "LAST", "LASTSITE"]
|
|||
|
||||
# Server version number.
|
||||
EVENNIA_VERSION = 'Pre-Alpha'
|
||||
|
||||
# The message to show when the user lacks permissions for something.
|
||||
NOPERMS_MSG = "You do not have the necessary permissions to do that."
|
||||
|
||||
# Message seen when object doesn't control the other object.
|
||||
NOCONTROL_MSG = "You don't have authority over that object."
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ class SessionProtocol(StatefulTelnetProtocol):
|
|||
return self.transport.client
|
||||
|
||||
def prep_session(self):
|
||||
#self.server = server
|
||||
self.server = self.factory.server
|
||||
self.address = self.getClientAddress()
|
||||
self.name = None
|
||||
self.uid = None
|
||||
|
|
@ -187,7 +187,7 @@ class SessionProtocol(StatefulTelnetProtocol):
|
|||
cmdhandler.handle(cdat)
|
||||
functions_general.log_infomsg("Login: %s" % (self,))
|
||||
pobject.set_attribute("Last", "%s" % (time.strftime("%a %b %d %H:%M:%S %Y", time.localtime()),))
|
||||
pobject.set_attribute("Lastsite", "%s" % (self.address,))
|
||||
pobject.set_attribute("Lastsite", "%s" % (self.address[0],))
|
||||
self.load_user_channels()
|
||||
|
||||
def msg(self, message):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue