mirror of
https://github.com/inventree/InvenTree.git
synced 2025-04-30 04:26:44 +00:00
commit
57d481a8b8
@ -1802,10 +1802,8 @@ class WebhookEndpoint(models.Model):
|
|||||||
def process_webhook(self):
|
def process_webhook(self):
|
||||||
if self.token:
|
if self.token:
|
||||||
self.verify = VerificationMethod.TOKEN
|
self.verify = VerificationMethod.TOKEN
|
||||||
# TODO make a object-setting
|
|
||||||
if self.secret:
|
if self.secret:
|
||||||
self.verify = VerificationMethod.HMAC
|
self.verify = VerificationMethod.HMAC
|
||||||
# TODO make a object-setting
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def validate_token(self, payload, headers, request):
|
def validate_token(self, payload, headers, request):
|
||||||
|
@ -31,12 +31,8 @@ class ActionPluginView(APIView):
|
|||||||
action_plugins = registry.with_mixin('action')
|
action_plugins = registry.with_mixin('action')
|
||||||
for plugin in action_plugins:
|
for plugin in action_plugins:
|
||||||
if plugin.action_name() == action:
|
if plugin.action_name() == action:
|
||||||
# TODO @matmair use easier syntax once InvenTree 0.7.0 is released
|
plugin.perform_action(request.user, data=data)
|
||||||
plugin.init(request.user, data=data)
|
return Response(plugin.get_response(request.user, data=data))
|
||||||
|
|
||||||
plugin.perform_action()
|
|
||||||
|
|
||||||
return Response(plugin.get_response())
|
|
||||||
|
|
||||||
# If we got to here, no matching action was found
|
# If we got to here, no matching action was found
|
||||||
return Response({
|
return Response({
|
||||||
|
@ -15,10 +15,9 @@ class ActionMixin:
|
|||||||
"""
|
"""
|
||||||
MIXIN_NAME = 'Actions'
|
MIXIN_NAME = 'Actions'
|
||||||
|
|
||||||
def __init__(self, user=None, data=None):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.add_mixin('action', True, __class__)
|
self.add_mixin('action', True, __class__)
|
||||||
self.init(user, data)
|
|
||||||
|
|
||||||
def action_name(self):
|
def action_name(self):
|
||||||
"""
|
"""
|
||||||
@ -31,19 +30,12 @@ class ActionMixin:
|
|||||||
return self.ACTION_NAME
|
return self.ACTION_NAME
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
def init(self, user, data=None):
|
def perform_action(self, user=None, data=None):
|
||||||
"""
|
|
||||||
An action plugin takes a user reference, and an optional dataset (dict)
|
|
||||||
"""
|
|
||||||
self.user = user
|
|
||||||
self.data = data
|
|
||||||
|
|
||||||
def perform_action(self):
|
|
||||||
"""
|
"""
|
||||||
Override this method to perform the action!
|
Override this method to perform the action!
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def get_result(self):
|
def get_result(self, user=None, data=None):
|
||||||
"""
|
"""
|
||||||
Result of the action?
|
Result of the action?
|
||||||
"""
|
"""
|
||||||
@ -51,19 +43,19 @@ class ActionMixin:
|
|||||||
# Re-implement this for cutsom actions
|
# Re-implement this for cutsom actions
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def get_info(self):
|
def get_info(self, user=None, data=None):
|
||||||
"""
|
"""
|
||||||
Extra info? Can be a string / dict / etc
|
Extra info? Can be a string / dict / etc
|
||||||
"""
|
"""
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_response(self):
|
def get_response(self, user=None, data=None):
|
||||||
"""
|
"""
|
||||||
Return a response. Default implementation is a simple response
|
Return a response. Default implementation is a simple response
|
||||||
which can be overridden.
|
which can be overridden.
|
||||||
"""
|
"""
|
||||||
return {
|
return {
|
||||||
"action": self.action_name(),
|
"action": self.action_name(),
|
||||||
"result": self.get_result(),
|
"result": self.get_result(user, data),
|
||||||
"info": self.get_info(),
|
"info": self.get_info(user, data),
|
||||||
}
|
}
|
||||||
|
@ -14,27 +14,27 @@ class ActionMixinTests(TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
class SimplePlugin(ActionMixin, InvenTreePlugin):
|
class SimplePlugin(ActionMixin, InvenTreePlugin):
|
||||||
pass
|
pass
|
||||||
self.plugin = SimplePlugin('user')
|
self.plugin = SimplePlugin()
|
||||||
|
|
||||||
class TestActionPlugin(ActionMixin, InvenTreePlugin):
|
class TestActionPlugin(ActionMixin, InvenTreePlugin):
|
||||||
"""a action plugin"""
|
"""a action plugin"""
|
||||||
ACTION_NAME = 'abc123'
|
ACTION_NAME = 'abc123'
|
||||||
|
|
||||||
def perform_action(self):
|
def perform_action(self, user=None, data=None):
|
||||||
return ActionMixinTests.ACTION_RETURN + 'action'
|
return ActionMixinTests.ACTION_RETURN + 'action'
|
||||||
|
|
||||||
def get_result(self):
|
def get_result(self, user=None, data=None):
|
||||||
return ActionMixinTests.ACTION_RETURN + 'result'
|
return ActionMixinTests.ACTION_RETURN + 'result'
|
||||||
|
|
||||||
def get_info(self):
|
def get_info(self, user=None, data=None):
|
||||||
return ActionMixinTests.ACTION_RETURN + 'info'
|
return ActionMixinTests.ACTION_RETURN + 'info'
|
||||||
|
|
||||||
self.action_plugin = TestActionPlugin('user')
|
self.action_plugin = TestActionPlugin()
|
||||||
|
|
||||||
class NameActionPlugin(ActionMixin, InvenTreePlugin):
|
class NameActionPlugin(ActionMixin, InvenTreePlugin):
|
||||||
NAME = 'Aplugin'
|
NAME = 'Aplugin'
|
||||||
|
|
||||||
self.action_name = NameActionPlugin('user')
|
self.action_name = NameActionPlugin()
|
||||||
|
|
||||||
def test_action_name(self):
|
def test_action_name(self):
|
||||||
"""check the name definition possibilities"""
|
"""check the name definition possibilities"""
|
||||||
|
@ -63,7 +63,6 @@ class BarcodeScan(APIView):
|
|||||||
plugin = None
|
plugin = None
|
||||||
|
|
||||||
for current_plugin in plugins:
|
for current_plugin in plugins:
|
||||||
# TODO @matmair make simpler after InvenTree 0.7.0 release
|
|
||||||
current_plugin.init(barcode_data)
|
current_plugin.init(barcode_data)
|
||||||
|
|
||||||
if current_plugin.validate():
|
if current_plugin.validate():
|
||||||
@ -168,7 +167,6 @@ class BarcodeAssign(APIView):
|
|||||||
plugin = None
|
plugin = None
|
||||||
|
|
||||||
for current_plugin in plugins:
|
for current_plugin in plugins:
|
||||||
# TODO @matmair make simpler after InvenTree 0.7.0 release
|
|
||||||
current_plugin.init(barcode_data)
|
current_plugin.init(barcode_data)
|
||||||
|
|
||||||
if current_plugin.validate():
|
if current_plugin.validate():
|
||||||
|
@ -13,14 +13,14 @@ class SimpleActionPlugin(ActionMixin, InvenTreePlugin):
|
|||||||
NAME = "SimpleActionPlugin"
|
NAME = "SimpleActionPlugin"
|
||||||
ACTION_NAME = "simple"
|
ACTION_NAME = "simple"
|
||||||
|
|
||||||
def perform_action(self):
|
def perform_action(self, user=None, data=None):
|
||||||
print("Action plugin in action!")
|
print("Action plugin in action!")
|
||||||
|
|
||||||
def get_info(self):
|
def get_info(self, user, data=None):
|
||||||
return {
|
return {
|
||||||
"user": self.user.username,
|
"user": user.username,
|
||||||
"hello": "world",
|
"hello": "world",
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_result(self):
|
def get_result(self, user=None, data=None):
|
||||||
return True
|
return True
|
||||||
|
@ -15,7 +15,7 @@ class SimpleActionPluginTests(TestCase):
|
|||||||
self.test_user = user.objects.create_user('testuser', 'test@testing.com', 'password')
|
self.test_user = user.objects.create_user('testuser', 'test@testing.com', 'password')
|
||||||
|
|
||||||
self.client.login(username='testuser', password='password')
|
self.client.login(username='testuser', password='password')
|
||||||
self.plugin = SimpleActionPlugin(user=self.test_user)
|
self.plugin = SimpleActionPlugin()
|
||||||
|
|
||||||
def test_name(self):
|
def test_name(self):
|
||||||
"""check plugn names """
|
"""check plugn names """
|
||||||
|
@ -133,7 +133,6 @@ class PluginsRegistry:
|
|||||||
if retry_counter <= 0: # pragma: no cover
|
if retry_counter <= 0: # pragma: no cover
|
||||||
if settings.PLUGIN_TESTING:
|
if settings.PLUGIN_TESTING:
|
||||||
print('[PLUGIN] Max retries, breaking loading')
|
print('[PLUGIN] Max retries, breaking loading')
|
||||||
# TODO error for server status
|
|
||||||
break
|
break
|
||||||
if settings.PLUGIN_TESTING:
|
if settings.PLUGIN_TESTING:
|
||||||
print(f'[PLUGIN] Above error occured during testing - {retry_counter}/{settings.PLUGIN_RETRY} retries left')
|
print(f'[PLUGIN] Above error occured during testing - {retry_counter}/{settings.PLUGIN_RETRY} retries left')
|
||||||
@ -301,7 +300,6 @@ class PluginsRegistry:
|
|||||||
# Errors are bad so disable the plugin in the database
|
# Errors are bad so disable the plugin in the database
|
||||||
if not settings.PLUGIN_TESTING: # pragma: no cover
|
if not settings.PLUGIN_TESTING: # pragma: no cover
|
||||||
plugin_db_setting.active = False
|
plugin_db_setting.active = False
|
||||||
# TODO save the error to the plugin
|
|
||||||
plugin_db_setting.save(no_reload=True)
|
plugin_db_setting.save(no_reload=True)
|
||||||
|
|
||||||
# Add to inactive plugins so it shows up in the ui
|
# Add to inactive plugins so it shows up in the ui
|
||||||
@ -310,8 +308,6 @@ class PluginsRegistry:
|
|||||||
|
|
||||||
# Initialize package
|
# Initialize package
|
||||||
# now we can be sure that an admin has activated the plugin
|
# now we can be sure that an admin has activated the plugin
|
||||||
# TODO check more stuff -> as of Nov 2021 there are not many checks in place
|
|
||||||
# but we could enhance those to check signatures, run the plugin against a whitelist etc.
|
|
||||||
logger.info(f'Loading plugin {plug_name}')
|
logger.info(f'Loading plugin {plug_name}')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user