Whitelist uses of stdlib random module for bandit
[mudpy.git] / mudpy / command.py
index 39e0a83..d72e4e3 100644 (file)
@@ -111,7 +111,9 @@ def error(actor, input_data):
     """Generic error for an unrecognized command word."""
 
     # 90% of the time use a generic error
-    if random.randrange(10):
+    # Whitelist the random.randrange() call in bandit since it's not used for
+    # security/cryptographic purposes
+    if random.randrange(10):  # nosec
         message = '''I'm not sure what "''' + input_data + '''" means...'''
 
     # 10% of the time use the classic diku error
@@ -263,10 +265,12 @@ def look(actor, parameters):
 
 def move(actor, parameters):
     """Move the avatar in a given direction."""
-    if parameters in actor.universe.contents[actor.get("location")].portals():
-        actor.move_direction(parameters)
-    else:
-        actor.send("You cannot go that way.")
+    for portal in sorted(
+            actor.universe.contents[actor.get("location")].portals()):
+        if portal.startswith(parameters):
+            actor.move_direction(portal)
+            return(portal)
+    actor.send("You cannot go that way.")
 
 
 def preferences(actor, parameters):
@@ -278,22 +282,31 @@ def preferences(actor, parameters):
     message = ""
     arguments = parameters.split()
     allowed_prefs = set()
+    base_prefs = []
     user_config = actor.universe.contents.get("mudpy.user")
     if user_config:
-        allowed_prefs.update(user_config.get("pref_allow", []))
+        base_prefs = user_config.get("pref_allow", [])
+        allowed_prefs.update(base_prefs)
         if actor.owner.account.get("administrator"):
             allowed_prefs.update(user_config.get("pref_admin", []))
     if not arguments:
         message += "These are your current preferences:"
-        for pref in allowed_prefs:
-            message += ("$(eol)   $(red)%s $(grn)%s$(nrm)"
-                        % (pref, actor.owner.account.get(pref)))
+
+        # color-code base and admin prefs
+        for pref in sorted(allowed_prefs):
+            if pref in base_prefs:
+                color = "grn"
+            else:
+                color = "red"
+            message += ("$(eol)   $(%s)%s$(nrm) - %s" % (
+                color, pref, actor.owner.account.get(pref, "<not set>")))
+
     elif arguments[0] not in allowed_prefs:
         message += (
             'Preference "%s" does not exist. Try the `preferences` command by '
             "itself for a list of valid preferences." % arguments[0])
     elif len(arguments) == 1:
-        message += "%s" % actor.owner.account.get(arguments[0])
+        message += "%s" % actor.owner.account.get(arguments[0], "<not set>")
     else:
         pref = arguments[0]
         value = " ".join(arguments[1:])
@@ -526,7 +539,12 @@ def show(actor, parameters):
             message = "You need to specify an expression."
         else:
             try:
-                message = repr(eval(" ".join(arguments[1:])))
+                # there is no other option than to use eval() for this, since
+                # its purpose is to evaluate arbitrary expressions, so do what
+                # we can to secure it and whitelist it for bandit analysis
+                message = repr(eval(  # nosec
+                    " ".join(arguments[1:]),
+                    {"mudpy": mudpy, "universe": actor.universe}))
             except Exception as e:
                 message = ("$(red)Your expression raised an exception...$(eol)"
                            "$(eol)$(bld)%s$(nrm)" % e)