New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow the script handler to wait for the script #1307
Changes from 1 commit
13c2c35
8f306eb
040d0db
bea2309
5fc5322
83f6eaa
e2b1d60
7bd3d27
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,6 +33,7 @@ | |
""" | ||
from privacyidea.lib.eventhandler.base import BaseEventHandler | ||
from privacyidea.lib.config import get_from_config | ||
from privacyidea.lib.error import ServerError | ||
from privacyidea.lib import _ | ||
import json | ||
import logging | ||
|
@@ -50,18 +51,23 @@ class ScriptEventHandler(BaseEventHandler): | |
""" | ||
An Eventhandler needs to return a list of actions, which it can handle. | ||
It also returns a list of allowed action and conditions | ||
It returns an identifier, which can be used in the eventhandlig definitions | ||
It returns an identifier, which can be used in the eventhandling definitions | ||
""" | ||
|
||
identifier = "Script" | ||
description = "This event handler can trigger external scripts." | ||
|
||
try: | ||
script_directory = get_from_config("PI_SCRIPT_HANDLER_DIRECTORY", | ||
"/etc/privacyidea/scripts") | ||
except RuntimeError: | ||
# In case of the tests we are outside of the application context | ||
script_directory = "tests/testdata/scripts" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
def __init__(self, script_directory=None): | ||
if not script_directory: | ||
try: | ||
self.script_directory = get_from_config("PI_SCRIPT_HANDLER_DIRECTORY", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this really be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in 5fc5322 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
"/etc/privacyidea/scripts") | ||
except RuntimeError: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in bea2309 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
# In case of the tests we are outside of the application context | ||
script_directory = "tests/testdata/scripts" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this should be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. True! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
|
||
else: | ||
self.script_directory = script_directory | ||
|
||
@property | ||
def allowed_positions(cls): | ||
|
@@ -180,26 +186,22 @@ def do(self, action, options=None): | |
proc_args.append("--logged_in_role") | ||
proc_args.append(logged_in_user.get("role", "none")) | ||
|
||
if handler_options.get("background", SCRIPT_BACKGROUND) == SCRIPT_BACKGROUND: | ||
try: | ||
p = subprocess.Popen(proc_args, cwd=self.script_directory) | ||
log.info("Started script {script!r} in background:" | ||
" {process!r}".format(script=script_name, process=p)) | ||
except Exception as e: | ||
log.warning("Failed to execute script {0!r}: {1!r}".format( | ||
script_name, e)) | ||
log.warning(traceback.format_exc()) | ||
|
||
elif handler_options.get("background") == SCRIPT_WAIT: | ||
try: | ||
log.info("Starting script {script!r} in foreground.".format(script=script_name)) | ||
r = subprocess.check_call(proc_args, cwd=self.script_directory) | ||
except Exception as e: | ||
log.warning("Failed to execute script {0!r}: {1!r}".format( | ||
script_name, e)) | ||
log.warning(traceback.format_exc()) | ||
if handler_options.get("raise_error"): | ||
raise e | ||
rcode = 0 | ||
try: | ||
log.info("Starting script {script!r}.".format(script=script_name)) | ||
p = subprocess.Popen(proc_args, cwd=self.script_directory) | ||
if handler_options.get("background") == SCRIPT_WAIT: | ||
rcode = p.wait() | ||
|
||
except Exception as e: | ||
log.warning("Failed to execute script {0!r}: {1!r}".format( | ||
script_name, e)) | ||
log.warning(traceback.format_exc()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we raise an error here if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We did not raise an error before. I would like to keep it that way. Imagine an event handler, that is supposed to write a backup to a SMB mount on every 100th auth request. Now the SMB is down or someone change a password or deleted the script. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But if I want to avoid that situation, I would probably set Anyway, I'm also OK with keeping this as it is. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are adding Feature requests in the reviews! ;-) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Currently "raise_error" can only be set for "background" mode. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in e2b1d60 :-) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
|
||
if rcode and handler_options.get("raise_error"): | ||
log.warning("Script {script!r} failed to execute with error code {error!r}".format(script=script_name, | ||
error=rcode)) | ||
raise ServerError("Error during execution of the script.") | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we add an else:
log.warning("Invalid value: {!r}".format(handler_options.get("background"))) ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, but I will add an else branch, if raise_error is not set. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
return ret | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍