mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Fix admin site - Custom admin URL (#5766)
* Update config template file * Add entry to docs * Add INVENTREE_ADMIN_ENABLED to settings.py * Add helper functions for improving admin links * Refactor existing admin links * remove debug statements * Fix custom admin URL * Expand documentation * Fix URL * Improve wording in config_template.yaml * Extend admin_url tag - Allow lookup without pk - Handle case where pk not found
This commit is contained in:
parent
388b722de1
commit
b335728e29
@ -197,7 +197,18 @@ if DBBACKUP_STORAGE_OPTIONS is None:
|
||||
'location': config.get_backup_dir(),
|
||||
}
|
||||
|
||||
# Application definition
|
||||
INVENTREE_ADMIN_ENABLED = get_boolean_setting(
|
||||
'INVENTREE_ADMIN_ENABLED',
|
||||
config_key='admin_enabled',
|
||||
default_value=True
|
||||
)
|
||||
|
||||
# Base URL for admin pages (default="admin")
|
||||
INVENTREE_ADMIN_URL = get_setting(
|
||||
'INVENTREE_ADMIN_URL',
|
||||
config_key='admin_url',
|
||||
default_value='admin'
|
||||
)
|
||||
|
||||
INSTALLED_APPS = [
|
||||
# Admin site integration
|
||||
@ -378,14 +389,6 @@ if DEBUG:
|
||||
INSTALLED_APPS.append('sslserver')
|
||||
|
||||
# InvenTree URL configuration
|
||||
|
||||
# Base URL for admin pages (default="admin")
|
||||
INVENTREE_ADMIN_URL = get_setting(
|
||||
'INVENTREE_ADMIN_URL',
|
||||
config_key='admin_url',
|
||||
default_value='admin'
|
||||
)
|
||||
|
||||
ROOT_URLCONF = 'InvenTree.urls'
|
||||
|
||||
TEMPLATES = [
|
||||
|
@ -209,11 +209,14 @@ classic_frontendpatterns = [
|
||||
|
||||
new_frontendpatterns = platform_urls
|
||||
|
||||
urlpatterns = [
|
||||
# admin sites
|
||||
re_path(f'^{settings.INVENTREE_ADMIN_URL}/error_log/', include('error_report.urls')),
|
||||
re_path(f'^{settings.INVENTREE_ADMIN_URL}/', admin.site.urls, name='inventree-admin'),
|
||||
]
|
||||
urlpatterns = []
|
||||
|
||||
if settings.INVENTREE_ADMIN_ENABLED:
|
||||
admin_url = settings.INVENTREE_ADMIN_URL,
|
||||
urlpatterns += [
|
||||
path(f'{admin_url}/error_log/', include('error_report.urls')),
|
||||
path(f'{admin_url}/', admin.site.urls, name='inventree-admin'),
|
||||
]
|
||||
|
||||
urlpatterns += backendpatterns
|
||||
|
||||
|
@ -29,10 +29,9 @@ src="{% static 'img/blank_image.png' %}"
|
||||
|
||||
{% block actions %}
|
||||
<!-- Admin Display -->
|
||||
{% if user.is_staff and roles.build.change %}
|
||||
{% url 'admin:build_build_change' build.pk as url %}
|
||||
{% admin_url user "build.build" build.pk as url %}
|
||||
{% include "admin_button.html" with url=url %}
|
||||
{% endif %}
|
||||
|
||||
{% if barcodes %}
|
||||
<!-- Barcode actions menu -->
|
||||
<div class='btn-group' role='group'>
|
||||
|
@ -14,10 +14,9 @@
|
||||
|
||||
{% block actions %}
|
||||
<!-- Admin View -->
|
||||
{% if user.is_staff and perms.company.change_company %}
|
||||
{% url 'admin:company_company_change' company.pk as url %}
|
||||
{% admin_url user "company.company" company.pk as url %}
|
||||
{% include "admin_button.html" with url=url %}
|
||||
{% endif %}
|
||||
|
||||
{% if company.is_supplier and roles.purchase_order.add %}
|
||||
<button type='button' class='btn btn-outline-primary' id='company-order-2' title='{% trans "Create Purchase Order" %}'>
|
||||
<span class='fas fa-shopping-cart'/>
|
||||
|
@ -26,10 +26,10 @@
|
||||
{% endblock heading %}
|
||||
|
||||
{% block actions %}
|
||||
{% if user.is_staff and perms.company.change_company %}
|
||||
{% url 'admin:company_manufacturerpart_change' part.pk as url %}
|
||||
|
||||
{% admin_url user 'company.manufacturerpart' part.pk as url %}
|
||||
{% include "admin_button.html" with url=url %}
|
||||
{% endif %}
|
||||
|
||||
{% if roles.purchase_order.change %}
|
||||
{% if roles.purchase_order.add and part.part.purchaseable %}
|
||||
<button type='button' class='btn btn-outline-secondary' id='order-part' title='{% trans "Order part" %}'>
|
||||
|
@ -26,10 +26,9 @@
|
||||
{% endblock heading %}
|
||||
|
||||
{% block actions %}
|
||||
{% if user.is_staff and perms.company.change_company %}
|
||||
{% url 'admin:company_supplierpart_change' part.pk as url %}
|
||||
{% admin_url user "company.supplierpart" part.pk as url %}
|
||||
{% include "admin_button.html" with url=url %}
|
||||
{% endif %}
|
||||
|
||||
{% if barcodes %}
|
||||
<!-- Barcode actions menu -->
|
||||
<div class='btn-group' role='group'>
|
||||
|
@ -58,6 +58,14 @@ database:
|
||||
# Use the environment variable INVENTREE_DEBUG
|
||||
debug: True
|
||||
|
||||
# Set to False to disable the admin interface (default = True)
|
||||
# Or, use the environment variable INVENTREE_ADMIN_ENABLED
|
||||
#admin_enabled: True
|
||||
|
||||
# Set the admin URL (default is 'admin')
|
||||
# Or, use the environment variable INVENTREE_ADMIN_URL
|
||||
#admin_url: 'admin'
|
||||
|
||||
# Set enabled frontends
|
||||
# Use the environment variable INVENTREE_CLASSIC_FRONTEND
|
||||
# classic_frontend: True
|
||||
|
@ -19,10 +19,10 @@
|
||||
{% endblock heading %}
|
||||
|
||||
{% block actions %}
|
||||
{% if user.is_staff and roles.purchase_order.change %}
|
||||
{% url 'admin:order_purchaseorder_change' order.pk as url %}
|
||||
|
||||
{% admin_url user "order.purchaseorder" order.pk as url %}
|
||||
{% include "admin_button.html" with url=url %}
|
||||
{% endif %}
|
||||
|
||||
{% if barcodes %}
|
||||
<!-- Barcode actions menu -->
|
||||
<div class='btn-group' role='group'>
|
||||
|
@ -29,10 +29,9 @@ src="{% static 'img/blank_image.png' %}"
|
||||
{% endblock heading %}
|
||||
|
||||
{% block actions %}
|
||||
{% if user.is_staff and roles.return_order.change %}
|
||||
{% url 'admin:order_returnorder_change' order.pk as url %}
|
||||
{% admin_url user "order.returnorder" order.pk as url %}
|
||||
{% include "admin_button.html" with url=url %}
|
||||
{% endif %}
|
||||
|
||||
{% if barcodes %}
|
||||
<!-- Barcode actions menu -->
|
||||
<div class='btn-group' role='group'>
|
||||
|
@ -29,10 +29,9 @@ src="{% static 'img/blank_image.png' %}"
|
||||
{% endblock heading %}
|
||||
|
||||
{% block actions %}
|
||||
{% if user.is_staff and roles.sales_order.change %}
|
||||
{% url 'admin:order_salesorder_change' order.pk as url %}
|
||||
{% admin_url user "order.salesorder" order.pk as url %}
|
||||
{% include "admin_button.html" with url=url %}
|
||||
{% endif %}
|
||||
|
||||
{% if barcodes %}
|
||||
<!-- Barcode actions menu -->
|
||||
<div class='btn-group' role='group'>
|
||||
|
@ -25,10 +25,11 @@
|
||||
{% endblock heading %}
|
||||
|
||||
{% block actions %}
|
||||
{% if category and user.is_staff and roles.part_category.change %}
|
||||
{% url 'admin:part_partcategory_change' category.pk as url %}
|
||||
{% if category %}
|
||||
{% admin_url user "part.partcategory" category.pk as url %}
|
||||
{% include "admin_button.html" with url=url %}
|
||||
{% endif %}
|
||||
|
||||
{% settings_value "STOCKTAKE_ENABLE" as stocktake_enable %}
|
||||
{% if stocktake_enable and roles.stocktake.add %}
|
||||
<button type='button' class='btn btn-outline-secondary' id='category-stocktake' title='{% trans "Perform stocktake for this part category" %}'>
|
||||
|
@ -18,10 +18,8 @@
|
||||
|
||||
{% block actions %}
|
||||
<!-- Admin View -->
|
||||
{% if user.is_staff and roles.part.change %}
|
||||
{% url 'admin:part_part_change' part.pk as url %}
|
||||
{% admin_url user "part.part" part.pk as url %}
|
||||
{% include "admin_button.html" with url=url %}
|
||||
{% endif %}
|
||||
|
||||
{% if starred_directly %}
|
||||
<button type='button' class='btn btn-outline-secondary' id='toggle-starred' title='{% trans "You are subscribed to notifications for this part" %}'>
|
||||
|
@ -8,7 +8,7 @@ from datetime import date, datetime
|
||||
from django import template
|
||||
from django.conf import settings as djangosettings
|
||||
from django.templatetags.static import StaticNode
|
||||
from django.urls import reverse
|
||||
from django.urls import NoReverseMatch, reverse
|
||||
from django.utils.html import format_html
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
@ -626,3 +626,52 @@ else: # pragma: no cover
|
||||
token.contents = ' '.join(bits)
|
||||
|
||||
return I18nStaticNode.handle_token(parser, token)
|
||||
|
||||
|
||||
@register.simple_tag()
|
||||
def admin_index(user):
|
||||
"""Return a URL for the admin interface"""
|
||||
|
||||
if not djangosettings.INVENTREE_ADMIN_ENABLED:
|
||||
return ''
|
||||
|
||||
if not user.is_staff:
|
||||
return ''
|
||||
|
||||
return reverse('admin:index')
|
||||
|
||||
|
||||
@register.simple_tag()
|
||||
def admin_url(user, table, pk):
|
||||
"""Generate a link to the admin site for the given model instance.
|
||||
|
||||
- If the admin site is disabled, an empty URL is returned
|
||||
- If the user is not a staff user, an empty URL is returned
|
||||
- If the user does not have the correct permission, an empty URL is returned
|
||||
"""
|
||||
|
||||
app, model = table.strip().split('.')
|
||||
|
||||
from django.urls import reverse
|
||||
|
||||
if not djangosettings.INVENTREE_ADMIN_ENABLED:
|
||||
return ""
|
||||
|
||||
if not user.is_staff:
|
||||
return ""
|
||||
|
||||
# Check the user has the correct permission
|
||||
perm_string = f"{app}.change_{model}"
|
||||
if not user.has_perm(perm_string):
|
||||
return ''
|
||||
|
||||
# Fallback URL
|
||||
url = reverse(f"admin:{app}_{model}_changelist")
|
||||
|
||||
if pk:
|
||||
try:
|
||||
url = reverse(f'admin:{app}_{model}_change', args=(pk,))
|
||||
except NoReverseMatch:
|
||||
pass
|
||||
|
||||
return url
|
||||
|
@ -17,7 +17,7 @@ from django.apps import apps
|
||||
from django.conf import settings
|
||||
from django.contrib import admin
|
||||
from django.db.utils import IntegrityError, OperationalError, ProgrammingError
|
||||
from django.urls import clear_url_caches, re_path
|
||||
from django.urls import clear_url_caches, path
|
||||
from django.utils.text import slugify
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
@ -620,13 +620,17 @@ class PluginsRegistry:
|
||||
|
||||
app_name = getattr(url, 'app_name', None)
|
||||
|
||||
admin_url = settings.INVENTREE_ADMIN_URL
|
||||
|
||||
if app_name == 'admin':
|
||||
urlpatterns[index] = re_path(r'^admin/', admin.site.urls, name='inventree-admin')
|
||||
urlpatterns[index] = path(f'{admin_url}/', admin.site.urls, name='inventree-admin')
|
||||
|
||||
if app_name == 'plugin':
|
||||
urlpatterns[index] = get_plugin_urls()
|
||||
|
||||
# Refresh the URL cache
|
||||
clear_url_caches()
|
||||
|
||||
# endregion
|
||||
|
||||
# region plugin registry hash calculations
|
||||
|
@ -25,10 +25,9 @@
|
||||
|
||||
{% block actions %}
|
||||
|
||||
{% if user.is_staff and roles.stock.change %}
|
||||
{% url 'admin:stock_stockitem_change' item.pk as url %}
|
||||
{% admin_url user "stock.stockitem" item.pk as url %}
|
||||
{% include "admin_button.html" with url=url %}
|
||||
{% endif %}
|
||||
|
||||
{% mixin_available "locate" as locate_available %}
|
||||
{% if plugins_enabled and locate_available %}
|
||||
<button id='locate-item-button' title='{% trans "Locate stock item" %}' class='btn btn-outline-secondary' typy='button'>
|
||||
|
@ -28,10 +28,11 @@
|
||||
{% block actions %}
|
||||
|
||||
<!-- Admin view -->
|
||||
{% if location and user.is_staff and roles.stock_location.change %}
|
||||
{% url 'admin:stock_stocklocation_change' location.pk as url %}
|
||||
{% if location %}
|
||||
{% admin_url user "stock.stocklocation" location.pk as url %}
|
||||
{% include "admin_button.html" with url=url %}
|
||||
{% endif %}
|
||||
|
||||
{% settings_value "STOCKTAKE_ENABLE" as stocktake_enable %}
|
||||
{% if stocktake_enable and roles.stocktake.add %}
|
||||
<button type='button' class='btn btn-outline-secondary' id='location-stocktake' title='{% trans "Perform stocktake for this stock location" %}'>
|
||||
|
@ -35,7 +35,7 @@
|
||||
<h4>{% trans "Plugins" %}</h4>
|
||||
{% include "spacer.html" %}
|
||||
<div class='btn-group' role='group'>
|
||||
{% url 'admin:plugin_pluginconfig_changelist' as url %}
|
||||
{% 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' %}"><span class='fas fa-plus-circle'></span> {% trans "Install Plugin" %}</button>
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
{% inventree_customize 'hide_admin_link' as hidden %}
|
||||
|
||||
{% if not hidden and user.is_staff %}
|
||||
{% if url and not hidden and user.is_staff %}
|
||||
<a href='{{ url }}'>
|
||||
<button id='admin-button' href='{{ url }}' title='{% trans "View in administration panel" %}' type='button' class='btn btn-primary admin-button'>
|
||||
<span class='fas fa-user-shield'></span>
|
||||
|
@ -139,7 +139,10 @@
|
||||
<ul class='dropdown-menu dropdown-menu-end inventree-navbar-menu'>
|
||||
{% if user.is_authenticated %}
|
||||
{% if user.is_staff and not hide_admin_link %}
|
||||
<li><a class='dropdown-item' href="{% url 'admin:index' %}"><span class="fas fa-user-shield"></span> {% trans "Admin" %}</a></li>
|
||||
{% admin_index user as admin_idx %}
|
||||
{% if admin_idx %}
|
||||
<li><a class='dropdown-item' href="{{ admin_idx }}"><span class="fas fa-user-shield"></span> {% trans "Admin" %}</a></li>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<li><a class='dropdown-item' href="{% url 'settings' %}"><span class="fas fa-cog"></span> {% trans "Settings" %}</a></li>
|
||||
<li><a class='dropdown-item' href="{% url 'account_logout' %}"><span class="fas fa-sign-out-alt"></span> {% trans "Logout" %}</a></li>
|
||||
|
@ -1,10 +1,11 @@
|
||||
{% extends "registration/logged_out.html" %}
|
||||
{% load i18n %}
|
||||
{% load inventree_extras %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<p>{% translate "You were logged out successfully." %}</p>
|
||||
|
||||
<p><a href="{% url 'admin:index' %}">{% translate 'Log in again' %}</a></p>
|
||||
<p><a href="{% url 'index' %}">{% translate 'Log in again' %}</a></p>
|
||||
|
||||
{% endblock content %}
|
||||
|
@ -55,10 +55,22 @@ The following basic options are available:
|
||||
| INVENTREE_LOG_LEVEL | log_level | Set level of logging to terminal | WARNING |
|
||||
| INVENTREE_DB_LOGGING | db_logging | Enable logging of database messages | False |
|
||||
| INVENTREE_TIMEZONE | timezone | Server timezone | UTC |
|
||||
| ADMIN_URL | admin_url | URL for accessing [admin interface](../settings/admin.md) | admin |
|
||||
| INVENTREE_ADMIN_ENABLED | admin_enabled | Enable the [django administrator interface](https://docs.djangoproject.com/en/4.2/ref/contrib/admin/) | True |
|
||||
| INVENTREE_ADMIN_URL | admin_url | URL for accessing [admin interface](../settings/admin.md) | admin |
|
||||
| INVENTREE_LANGUAGE | language | Default language | en-us |
|
||||
| INVENTREE_BASE_URL | base_url | Server base URL | *Not specified* |
|
||||
|
||||
### Admin Site
|
||||
|
||||
Django provides a powerful [administrator interface](https://docs.djangoproject.com/en/4.2/ref/contrib/admin/) which can be used to manage the InvenTree database. This interface is enabled by default, but can be disabled by setting `INVENTREE_ADMIN_ENABLED` to `False`.
|
||||
|
||||
#### Custom Admin URL
|
||||
|
||||
By default, the admin interface is available at the `/admin/` URL. This can be changed by setting the `INVENTREE_ADMIN_URL` environment variable.
|
||||
|
||||
!!! warning "Security"
|
||||
Changing the admin URL is a simple way to improve security, but it is not a substitute for proper security practices.
|
||||
|
||||
### Base URL Configuration
|
||||
|
||||
The base URL of the InvenTree site is required for constructing absolute URLs in a number of circumstances. To construct a URL, the InvenTree iterates through the following options in decreasing order of importance:
|
||||
|
Loading…
Reference in New Issue
Block a user