mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-05-20 10:34:30 +00:00
made actions.py more pep8 compliant; added one more check to verify that an action is within the actions directory; moved actions directory path into the settings instead of hard-coding it
This commit is contained in:
parent
aa65205403
commit
a40d42eb60
43
actions.py
43
actions.py
@ -47,11 +47,11 @@ Actions run commands with this contract (version 1.1):
|
|||||||
$ $action # oops, the file system is gone!
|
$ $action # oops, the file system is gone!
|
||||||
|
|
||||||
Arguments that fail this validation won't, but probably should, raise a
|
Arguments that fail this validation won't, but probably should, raise a
|
||||||
ValueError. They don't because sanitizing this case is significantly
|
ValueError. They don't because sanitizing this case is significantly
|
||||||
easier than detecting if it occurs.
|
easier than detecting if it occurs.
|
||||||
|
|
||||||
The options list is coerced into a space-separated string before being
|
The options list is coerced into a space-separated string before being
|
||||||
shell-escaped. Option lists including shell escape characters may need to
|
shell-escaped. Option lists including shell escape characters may need to
|
||||||
be unescaped on the receiving end.
|
be unescaped on the receiving end.
|
||||||
|
|
||||||
E. Actions must exist in the actions directory.
|
E. Actions must exist in the actions directory.
|
||||||
@ -73,46 +73,44 @@ Actions run commands with this contract (version 1.1):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import pipes, shlex, subprocess
|
import pipes
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
import cfg
|
||||||
|
|
||||||
|
|
||||||
def run(action, options = None, async = False):
|
def run(action, options=None, async=False):
|
||||||
"""Safely run a specific action as the current user.
|
"""Safely run a specific action as the current user.
|
||||||
|
|
||||||
See actions._run for more information.
|
See actions._run for more information.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return _run(action, options, async, False)
|
return _run(action, options, async, False)
|
||||||
|
|
||||||
def superuser_run(action, options = None, async = False):
|
|
||||||
|
def superuser_run(action, options=None, async=False):
|
||||||
"""Safely run a specific action as root.
|
"""Safely run a specific action as root.
|
||||||
|
|
||||||
See actions._run for more information.
|
See actions._run for more information.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return _run(action, options, async, True)
|
return _run(action, options, async, True)
|
||||||
|
|
||||||
def _run(action, options = None, async = False, run_as_root = False):
|
|
||||||
|
def _run(action, options=None, async=False, run_as_root=False):
|
||||||
"""Safely run a specific action as a normal user or root.
|
"""Safely run a specific action as a normal user or root.
|
||||||
|
|
||||||
actions are pulled from the actions directory.
|
actions are pulled from the actions directory.
|
||||||
|
- options are added to the action command.
|
||||||
options are added to the action command.
|
- async: run asynchronously or wait for the command to complete.
|
||||||
|
- run_as_root: execute the command through sudo.
|
||||||
async: run asynchronously or wait for the command to complete.
|
|
||||||
|
|
||||||
run_as_root: execute the command through sudo.
|
|
||||||
"""
|
"""
|
||||||
DIRECTORY = "actions"
|
|
||||||
|
|
||||||
if options == None:
|
if options is None:
|
||||||
options = []
|
options = []
|
||||||
|
|
||||||
# contract 3A and 3B: don't call anything outside of the actions directory.
|
# contract 3A and 3B: don't call anything outside of the actions directory.
|
||||||
if os.sep in action:
|
if os.sep in action:
|
||||||
raise ValueError("Action can't contain:" + os.sep)
|
raise ValueError("Action can't contain:" + os.sep)
|
||||||
|
|
||||||
cmd = DIRECTORY + os.sep + action
|
cmd = cfg.actions_dir + os.sep + action
|
||||||
|
if not os.path.realpath(cmd).startswith(cfg.actions_dir):
|
||||||
|
raise ValueError("Action has to be in directory %s" % cfg.actions_dir)
|
||||||
|
|
||||||
# contract 3C: interpret shell escape sequences as literal file names.
|
# contract 3C: interpret shell escape sequences as literal file names.
|
||||||
# contract 3E: fail if the action doesn't exist or exists elsewhere.
|
# contract 3E: fail if the action doesn't exist or exists elsewhere.
|
||||||
@ -125,7 +123,6 @@ def _run(action, options = None, async = False, run_as_root = False):
|
|||||||
if options:
|
if options:
|
||||||
if not hasattr(options, "__iter__"):
|
if not hasattr(options, "__iter__"):
|
||||||
options = [options]
|
options = [options]
|
||||||
|
|
||||||
cmd += [pipes.quote(option) for option in options]
|
cmd += [pipes.quote(option) for option in options]
|
||||||
|
|
||||||
# contract 1: commands can run via sudo.
|
# contract 1: commands can run via sudo.
|
||||||
@ -136,8 +133,8 @@ def _run(action, options = None, async = False, run_as_root = False):
|
|||||||
# contract 5 (and 6-ish).
|
# contract 5 (and 6-ish).
|
||||||
proc = subprocess.Popen(
|
proc = subprocess.Popen(
|
||||||
cmd,
|
cmd,
|
||||||
stdout = subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
stderr= subprocess.PIPE,
|
stderr=subprocess.PIPE,
|
||||||
shell=False)
|
shell=False)
|
||||||
|
|
||||||
if not async:
|
if not async:
|
||||||
|
|||||||
1
cfg.py
1
cfg.py
@ -41,6 +41,7 @@ def read():
|
|||||||
('Path', 'data_dir'),
|
('Path', 'data_dir'),
|
||||||
('Path', 'store_file'),
|
('Path', 'store_file'),
|
||||||
('Path', 'user_db'),
|
('Path', 'user_db'),
|
||||||
|
('Path', 'actions_dir'),
|
||||||
('Path', 'status_log_file'),
|
('Path', 'status_log_file'),
|
||||||
('Path', 'access_log_file'),
|
('Path', 'access_log_file'),
|
||||||
('Path', 'pidfile'),
|
('Path', 'pidfile'),
|
||||||
|
|||||||
@ -10,6 +10,7 @@ log_dir = %(data_dir)s
|
|||||||
pid_dir = %(data_dir)s
|
pid_dir = %(data_dir)s
|
||||||
python_root = %(file_root)s
|
python_root = %(file_root)s
|
||||||
server_dir = plinth/
|
server_dir = plinth/
|
||||||
|
actions_dir = %(file_root)s/actions
|
||||||
|
|
||||||
# file locations
|
# file locations
|
||||||
store_file = %(data_dir)s/store.sqlite3
|
store_file = %(data_dir)s/store.sqlite3
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user