mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Add config option to fully disable installing plugins (#6535)
* [FR] Add config option to fully disable installing plugins Fixes #6531 * also restrict uninstalling * Added test * diff cleanup * extend api to show if install was disabled * PUI disable install buttons * CUI disable install button if not available * add config option * Rephrase
This commit is contained in:
parent
85225538e6
commit
75c24fb8f4
@ -152,6 +152,7 @@ class InfoView(AjaxView):
|
||||
'worker_running': is_worker_running(),
|
||||
'worker_pending_tasks': self.worker_pending_tasks(),
|
||||
'plugins_enabled': settings.PLUGINS_ENABLED,
|
||||
'plugins_install_disabled': settings.PLUGINS_INSTALL_DISABLED,
|
||||
'active_plugins': plugins_info(),
|
||||
'email_configured': is_email_configured(),
|
||||
'debug_mode': settings.DEBUG,
|
||||
|
@ -1,11 +1,14 @@
|
||||
"""InvenTree API version information."""
|
||||
|
||||
# InvenTree API version
|
||||
INVENTREE_API_VERSION = 175
|
||||
INVENTREE_API_VERSION = 176
|
||||
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
|
||||
|
||||
INVENTREE_API_TEXT = """
|
||||
|
||||
v176 - 2024-02-26 : https://github.com/inventree/InvenTree/pull/6535
|
||||
- Adds the field "plugins_install_disabled" to the Server info API endpoint
|
||||
|
||||
v175 - 2024-02-21 : https://github.com/inventree/InvenTree/pull/6538
|
||||
- Adds "parts" count to PartParameterTemplate serializer
|
||||
|
||||
|
@ -1136,6 +1136,9 @@ MAINTENANCE_MODE_STATE_BACKEND = 'InvenTree.backends.InvenTreeMaintenanceModeBac
|
||||
PLUGINS_ENABLED = get_boolean_setting(
|
||||
'INVENTREE_PLUGINS_ENABLED', 'plugins_enabled', False
|
||||
)
|
||||
PLUGINS_INSTALL_DISABLED = get_boolean_setting(
|
||||
'INVENTREE_PLUGIN_NOINSTALL', 'plugin_noinstall', False
|
||||
)
|
||||
|
||||
PLUGIN_FILE = config.get_plugin_file()
|
||||
|
||||
|
@ -155,6 +155,12 @@ def plugins_enabled(*args, **kwargs):
|
||||
return djangosettings.PLUGINS_ENABLED
|
||||
|
||||
|
||||
@register.simple_tag()
|
||||
def plugins_install_disabled(*args, **kwargs):
|
||||
"""Return True if plugin install is disabled for the server instance."""
|
||||
return djangosettings.PLUGINS_INSTALL_DISABLED
|
||||
|
||||
|
||||
@register.simple_tag()
|
||||
def plugins_info(*args, **kwargs):
|
||||
"""Return information about activated plugins."""
|
||||
|
@ -152,6 +152,7 @@ sentry_enabled: False
|
||||
# Set this variable to True to enable InvenTree Plugins
|
||||
# Alternatively, use the environment variable INVENTREE_PLUGINS_ENABLED
|
||||
plugins_enabled: False
|
||||
#plugin_noinstall: True
|
||||
#plugin_file: '/path/to/plugins.txt'
|
||||
#plugin_dir: '/path/to/plugins/'
|
||||
|
||||
|
@ -55,6 +55,10 @@ class TemplateTagTest(InvenTreeTestCase):
|
||||
"""Test the plugins_enabled tag."""
|
||||
self.assertEqual(inventree_extras.plugins_enabled(), True)
|
||||
|
||||
def test_plugins_install_disabled(self):
|
||||
"""Test the plugins_install_disabled tag."""
|
||||
self.assertEqual(inventree_extras.plugins_install_disabled(), False)
|
||||
|
||||
def test_inventree_instance_name(self):
|
||||
"""Test the 'instance name' setting."""
|
||||
self.assertEqual(inventree_extras.inventree_instance_name(), 'InvenTree')
|
||||
|
@ -193,6 +193,9 @@ def install_plugin(url=None, packagename=None, user=None, version=None):
|
||||
if user and not user.is_staff:
|
||||
raise ValidationError(_('Only staff users can administer plugins'))
|
||||
|
||||
if settings.PLUGINS_INSTALL_DISABLED:
|
||||
raise ValidationError(_('Plugin installation is disabled'))
|
||||
|
||||
logger.info('install_plugin: %s, %s', url, packagename)
|
||||
|
||||
# Check if we are running in a virtual environment
|
||||
@ -292,6 +295,9 @@ def uninstall_plugin(cfg: plugin.models.PluginConfig, user=None, delete_config=T
|
||||
"""
|
||||
from plugin.registry import registry
|
||||
|
||||
if settings.PLUGINS_INSTALL_DISABLED:
|
||||
raise ValidationError(_('Plugin uninstalling is disabled'))
|
||||
|
||||
if cfg.active:
|
||||
raise ValidationError(
|
||||
_('Plugin cannot be uninstalled as it is currently active')
|
||||
|
@ -1,5 +1,6 @@
|
||||
"""Tests for general API tests for the plugin app."""
|
||||
|
||||
from django.conf import settings
|
||||
from django.urls import reverse
|
||||
|
||||
from rest_framework.exceptions import NotFound
|
||||
@ -81,6 +82,11 @@ class PluginDetailAPITest(PluginMixin, InvenTreeAPITestCase):
|
||||
data['confirm'][0].title().upper(), 'Installation not confirmed'.upper()
|
||||
)
|
||||
|
||||
# install disabled
|
||||
settings.PLUGINS_INSTALL_DISABLED = True
|
||||
self.post(url, {}, expected_code=400)
|
||||
settings.PLUGINS_INSTALL_DISABLED = False
|
||||
|
||||
def test_plugin_activate(self):
|
||||
"""Test the plugin activate."""
|
||||
test_plg = self.plugin_confs.first()
|
||||
|
@ -29,6 +29,7 @@
|
||||
</div>
|
||||
|
||||
{% plugins_enabled as plug %}
|
||||
{% plugins_install_disabled as plug_disabled %}
|
||||
|
||||
<div class='panel-heading'>
|
||||
<div class='d-flex flex-wrap'>
|
||||
@ -38,7 +39,7 @@
|
||||
{% admin_url user "plugin.pluginconfig" None as url %}
|
||||
{% include "admin_button.html" with url=url %}
|
||||
{% if plug %}
|
||||
<button class="btn btn-success" id="install-plugin" title="{% trans 'Install Plugin' %}">
|
||||
<button class="btn btn-success" id="install-plugin" title="{% trans 'Install Plugin' %}"{% if plug_disabled %}disabled{% endif %}>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "Install Plugin" %}
|
||||
</button>
|
||||
<button class='btn btn-success' id='reload-plugins' title='{% trans "Reload Plugins" %}'>
|
||||
|
@ -324,6 +324,7 @@ The following [plugin](../extend/plugins.md) configuration options are available
|
||||
| Environment Variable | Configuration File | Description | Default |
|
||||
| --- | --- | --- | --- |
|
||||
| INVENTREE_PLUGINS_ENABLED | plugins_enabled | Enable plugin support | False |
|
||||
| INVENTREE_PLUGIN_NOINSTALL | plugin_noinstall | Disable Plugin installation via API - only use plugins.txt file | False |
|
||||
| INVENTREE_PLUGIN_FILE | plugins_plugin_file | Location of plugin installation file | *Not specified* |
|
||||
| INVENTREE_PLUGIN_DIR | plugins_plugin_dir | Location of external plugin directory | *Not specified* |
|
||||
|
||||
|
@ -8,6 +8,7 @@ export const emptyServerAPI = {
|
||||
worker_running: null,
|
||||
worker_pending_tasks: null,
|
||||
plugins_enabled: null,
|
||||
plugins_install_disabled: null,
|
||||
active_plugins: [],
|
||||
email_configured: null,
|
||||
debug_mode: null,
|
||||
|
@ -34,6 +34,7 @@ export interface ServerAPIProps {
|
||||
worker_running: null | boolean;
|
||||
worker_pending_tasks: null | number;
|
||||
plugins_enabled: null | boolean;
|
||||
plugins_install_disabled: null | boolean;
|
||||
active_plugins: PluginProps[];
|
||||
email_configured: null | boolean;
|
||||
debug_mode: null | boolean;
|
||||
|
@ -14,6 +14,7 @@ export type RowAction = {
|
||||
icon: ReactNode;
|
||||
onClick?: () => void;
|
||||
hidden?: boolean;
|
||||
disabled?: boolean;
|
||||
};
|
||||
|
||||
// Component for duplicating a row in a table
|
||||
@ -129,6 +130,7 @@ export function RowActions({
|
||||
|
||||
setOpened(false);
|
||||
}}
|
||||
disabled={action.disabled || false}
|
||||
>
|
||||
{action.title}
|
||||
</Menu.Item>
|
||||
|
@ -271,8 +271,11 @@ export default function PluginListTable() {
|
||||
const navigate = useNavigate();
|
||||
const user = useUserState();
|
||||
|
||||
const pluginsEnabled = useServerApiState(
|
||||
(state) => state.server.plugins_enabled
|
||||
const [pluginsEnabled, plugins_install_disabled] = useServerApiState(
|
||||
(state) => [
|
||||
state.server.plugins_enabled,
|
||||
state.server.plugins_install_disabled
|
||||
]
|
||||
);
|
||||
|
||||
const pluginTableColumns: TableColumn[] = useMemo(
|
||||
@ -457,7 +460,8 @@ export default function PluginListTable() {
|
||||
onClick: () => {
|
||||
setSelectedPlugin(record.pk);
|
||||
uninstallPluginModal.open();
|
||||
}
|
||||
},
|
||||
disabled: plugins_install_disabled || false
|
||||
});
|
||||
}
|
||||
|
||||
@ -592,6 +596,7 @@ export default function PluginListTable() {
|
||||
setPluginPackage('');
|
||||
installPluginModal.open();
|
||||
}}
|
||||
disabled={plugins_install_disabled || false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user