Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
SergeoLacruz authored Oct 26, 2024
2 parents a4ad62f + 9fd882f commit 9f2691a
Show file tree
Hide file tree
Showing 164 changed files with 139,147 additions and 127,469 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ jobs:
- name: Build frontend
run: cd src/frontend && npm run compile && npm run build
- name: Create SBOM for frontend
uses: anchore/sbom-action@f5e124a5e5e1d497a692818ae907d3c45829d033 # pin@v0
uses: anchore/sbom-action@8d0a6505bf28ced3e85154d13dc6af83299e13f1 # pin@v0
with:
artifact-name: frontend-build.spdx
path: src/frontend
Expand Down
8 changes: 4 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ repos:
- id: check-yaml
- id: mixed-line-ending
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.8
rev: v0.7.0
hooks:
- id: ruff-format
args: [--preview]
Expand All @@ -28,7 +28,7 @@ repos:
--preview
]
- repo: https://github.com/astral-sh/uv-pre-commit
rev: 0.4.17
rev: 0.4.24
hooks:
- id: pip-compile
name: pip-compile requirements-dev.in
Expand Down Expand Up @@ -78,7 +78,7 @@ repos:
- "prettier@^2.4.1"
- "@trivago/prettier-plugin-sort-imports"
- repo: https://github.com/pre-commit/mirrors-eslint
rev: "v9.11.1"
rev: "v9.12.0"
hooks:
- id: eslint
additional_dependencies:
Expand All @@ -90,7 +90,7 @@ repos:
- "@typescript-eslint/parser"
files: ^src/frontend/.*\.(js|jsx|ts|tsx)$
- repo: https://github.com/gitleaks/gitleaks
rev: v8.19.3
rev: v8.21.0
hooks:
- id: gitleaks
#- repo: https://github.com/jumanjihouse/pre-commit-hooks
Expand Down
212 changes: 111 additions & 101 deletions contrib/container/requirements.txt

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/docs/develop/react-frontend.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Run the command `invoke int.frontend-compile`. Wait for this to finish
After finishing the install, you need to launch a frontend server to be able to view the new UI.

Using the previously described ways of running commands, execute the following:
`invoke dev.frontend-dev` in your environment
`invoke dev.frontend-server` in your environment
This command does not run as a background daemon, and will occupy the window it's ran in.

### Accessing
Expand Down
49 changes: 49 additions & 0 deletions docs/docs/start/accounts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
title: Account Management
---

## User Accounts

By default, InvenTree does not ship with any user accounts. Configuring user accounts is the first step to login to the InvenTree server.

### Administrator Account

You can configure InvenTree to create an administrator account on the first run. This account will have full *superuser* access to the InvenTree server.

This account is created when you first run the InvenTree server instance. The username / password for this account can be configured in the configuration file, or environment variables.

!!! info "More Information"
For more information on configuring the administrator account, refer to the [configuration documentation](./config.md#administrator-account).

### Create Superuser

Another way to create an administrator account is to use the `superuser` command. This will create a new superuser account with the specified username and password.

```bash
invoke superuser
```

Or, if you are running InvenTree in a Docker container:

```bash
docker exec -rm -it inventree-server invoke superuser
```

### User Management

Once you have created an administrator account, you can create and manage additional user accounts from the InvenTree web interface.

## Password Management

### Reset Password via Command Line

If a password has been lost, and other backup options (such as email recovery) are unavailable, the system administrator can reset the password for a user account from the command line.

Log into the machine running the InvenTree server, and run the following command (from the top-level source directory):

```bash
cd src/backend/InvenTree
python ./manage.py changepassword <username>
```

The system will prompt you to enter a new password for the specified user account.
1 change: 1 addition & 0 deletions docs/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ nav:
- Production: start/bare_prod.md
- Development: start/bare_dev.md
- Serving Files: start/serving_files.md
- User Accounts: start/accounts.md
- Data Backup: start/backup.md
- Migrating Data: start/migrate.md
- Advanced Topics: start/advanced.md
Expand Down
12 changes: 6 additions & 6 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -315,13 +315,13 @@ mkdocs-include-markdown-plugin==6.2.2 \
--hash=sha256:d293950f6499d2944291ca7b9bc4a60e652bbfd3e3a42b564f6cceee268694e7 \
--hash=sha256:f2bd5026650492a581d2fd44be6c22f90391910d76582b96a34c264f2d17875d
# via -r docs/requirements.in
mkdocs-macros-plugin==1.3.5 \
--hash=sha256:58bd47ea7097d1a2824dc9d0d912c211823c5e6e6fe8a19a3ecf33346f7d6547 \
--hash=sha256:5fd6969e2c43e23031ffb719bebe7421163ea26f4dc360af2343144ca979b04b
mkdocs-macros-plugin==1.3.6 \
--hash=sha256:074bc072cac14c28724037b6988743cd9425752bdd35ae05fbf96b1b2457f3b7 \
--hash=sha256:74fd418c8e1f9f021b7a45bb1c7d7461d8ae09ccec241787f3971e733374da8c
# via -r docs/requirements.in
mkdocs-material==9.5.40 \
--hash=sha256:8e7a16ada34e79a7b6459ff2602584222f522c738b6a023d1bea853d5049da6f \
--hash=sha256:b69d70e667ec51fc41f65e006a3184dd00d95b2439d982cb1586e4c018943156
mkdocs-material==9.5.42 \
--hash=sha256:452a7c5d21284b373f36b981a2cbebfff59263feebeede1bc28652e9c5bbe316 \
--hash=sha256:92779b5e9b5934540c574c11647131d217dc540dce72b05feeda088c8eb1b8f2
# via -r docs/requirements.in
mkdocs-material-extensions==1.3.1 \
--hash=sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443 \
Expand Down
11 changes: 10 additions & 1 deletion src/backend/InvenTree/InvenTree/api_version.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
"""InvenTree API version information."""

# InvenTree API version
INVENTREE_API_VERSION = 269
INVENTREE_API_VERSION = 272

"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""


INVENTREE_API_TEXT = """
v272 - 2024-10-25 : https://github.com/inventree/InvenTree/pull/8343
- Adjustments to BuildLine API serializers
v271 - 2024-10-22 : https://github.com/inventree/InvenTree/pull/8331
- Fixes for SalesOrderLineItem endpoints
v270 - 2024-10-19 : https://github.com/inventree/InvenTree/pull/8307
- Adds missing date fields from order API endpoint(s)
v269 - 2024-10-16 : https://github.com/inventree/InvenTree/pull/8295
- Adds "include_variants" filter to the BuildOrder API endpoint
- Adds "include_variants" filter to the SalesOrder API endpoint
Expand Down
10 changes: 7 additions & 3 deletions src/backend/InvenTree/InvenTree/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,14 @@ def ready(self):
- Adding users set in the current environment
"""
# skip loading if plugin registry is not loaded or we run in a background thread

if not InvenTree.ready.isPluginRegistryLoaded():
return

# Skip if not in worker or main thread
if (
not InvenTree.ready.isPluginRegistryLoaded()
or not InvenTree.ready.isInMainThread()
not InvenTree.ready.isInMainThread()
and not InvenTree.ready.isInWorkerThread()
):
return

Expand All @@ -52,7 +57,6 @@ def ready(self):

if InvenTree.ready.canAppAccessDatabase() or settings.TESTING_ENV:
self.remove_obsolete_tasks()

self.collect_tasks()
self.start_background_tasks()

Expand Down
32 changes: 29 additions & 3 deletions src/backend/InvenTree/InvenTree/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from django.utils import timezone
from django.utils.translation import gettext_lazy as _

import bleach
import pytz
import regex
from bleach import clean
Expand Down Expand Up @@ -829,7 +830,6 @@ def clean_markdown(value: str):
This function will remove javascript and other potentially harmful content from the markdown string.
"""
import markdown
from markdownify.templatetags.markdownify import markdownify

try:
markdownify_settings = settings.MARKDOWNIFY['default']
Expand All @@ -848,8 +848,34 @@ def clean_markdown(value: str):
output_format='html',
)

# Clean the HTML content (for comparison). Ideally, this should be the same as the original content
clean_html = markdownify(value)
# Bleach settings
whitelist_tags = markdownify_settings.get(
'WHITELIST_TAGS', bleach.sanitizer.ALLOWED_TAGS
)
whitelist_attrs = markdownify_settings.get(
'WHITELIST_ATTRS', bleach.sanitizer.ALLOWED_ATTRIBUTES
)
whitelist_styles = markdownify_settings.get(
'WHITELIST_STYLES', bleach.css_sanitizer.ALLOWED_CSS_PROPERTIES
)
whitelist_protocols = markdownify_settings.get(
'WHITELIST_PROTOCOLS', bleach.sanitizer.ALLOWED_PROTOCOLS
)
strip = markdownify_settings.get('STRIP', True)

css_sanitizer = bleach.css_sanitizer.CSSSanitizer(
allowed_css_properties=whitelist_styles
)
cleaner = bleach.Cleaner(
tags=whitelist_tags,
attributes=whitelist_attrs,
css_sanitizer=css_sanitizer,
protocols=whitelist_protocols,
strip=strip,
)

# Clean the HTML content (for comparison). This must be the same as the original content
clean_html = cleaner.clean(html)

if html != clean_html:
raise ValidationError(_('Data contains prohibited markdown content'))
Expand Down
1 change: 1 addition & 0 deletions src/backend/InvenTree/InvenTree/helpers_email.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,5 @@ def send_email(subject, body, recipients, from_email=None, html_message=None):
recipients,
fail_silently=False,
html_message=html_message,
group='notification',
)
107 changes: 77 additions & 30 deletions src/backend/InvenTree/InvenTree/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.urls import reverse
from django.urls.exceptions import NoReverseMatch
from django.utils.translation import gettext_lazy as _

from django_q.models import Task
from error_report.models import Error
from mptt.exceptions import InvalidMove
from mptt.models import MPTTModel, TreeForeignKey
Expand Down Expand Up @@ -1051,6 +1053,71 @@ def unassign_barcode(self):
self.save()


def notify_staff_users_of_error(instance, label: str, context: dict):
"""Helper function to notify staff users of an error."""
import common.models
import common.notifications

try:
# Get all staff users
staff_users = get_user_model().objects.filter(is_staff=True)

target_users = []

# Send a notification to each staff user (unless they have disabled error notifications)
for user in staff_users:
if common.models.InvenTreeUserSetting.get_setting(
'NOTIFICATION_ERROR_REPORT', True, user=user
):
target_users.append(user)

if len(target_users) > 0:
common.notifications.trigger_notification(
instance,
label,
context=context,
targets=target_users,
delivery_methods={common.notifications.UIMessageNotification},
)

except Exception as exc:
# We do not want to throw an exception while reporting an exception!
logger.error(exc)


@receiver(post_save, sender=Task, dispatch_uid='failure_post_save_notification')
def after_failed_task(sender, instance: Task, created: bool, **kwargs):
"""Callback when a new task failure log is generated."""
from django.conf import settings

max_attempts = int(settings.Q_CLUSTER.get('max_attempts', 5))
n = instance.attempt_count

# Only notify once the maximum number of attempts has been reached
if not instance.success and n >= max_attempts:
try:
url = InvenTree.helpers_model.construct_absolute_url(
reverse(
'admin:django_q_failure_change', kwargs={'object_id': instance.pk}
)
)
except (ValueError, NoReverseMatch):
url = ''

notify_staff_users_of_error(
instance,
'inventree.task_failure',
{
'failure': instance,
'name': _('Task Failure'),
'message': _(
f"Background worker task '{instance.func}' failed after {n} attempts"
),
'link': url,
},
)


@receiver(post_save, sender=Error, dispatch_uid='error_post_save_notification')
def after_error_logged(sender, instance: Error, created: bool, **kwargs):
"""Callback when a server error is logged.
Expand All @@ -1059,41 +1126,21 @@ def after_error_logged(sender, instance: Error, created: bool, **kwargs):
"""
if created:
try:
import common.models
import common.notifications

users = get_user_model().objects.filter(is_staff=True)

link = InvenTree.helpers_model.construct_absolute_url(
url = InvenTree.helpers_model.construct_absolute_url(
reverse(
'admin:error_report_error_change', kwargs={'object_id': instance.pk}
)
)
except NoReverseMatch:
url = ''

context = {
notify_staff_users_of_error(
instance,
'inventree.error_log',
{
'error': instance,
'name': _('Server Error'),
'message': _('An error has been logged by the server.'),
'link': link,
}

target_users = []

for user in users:
if common.models.InvenTreeUserSetting.get_setting(
'NOTIFICATION_ERROR_REPORT', True, user=user
):
target_users.append(user)

if len(target_users) > 0:
common.notifications.trigger_notification(
instance,
'inventree.error_log',
context=context,
targets=target_users,
delivery_methods={common.notifications.UIMessageNotification},
)

except Exception as exc:
"""We do not want to throw an exception while reporting an exception"""
logger.error(exc)
'link': url,
},
)
3 changes: 2 additions & 1 deletion src/backend/InvenTree/InvenTree/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@

checkMinPythonVersion()

INVENTREE_NEWS_URL = 'https://inventree.org/news/feed.atom'
INVENTREE_BASE_URL = 'https://inventree.org'
INVENTREE_NEWS_URL = f'{INVENTREE_BASE_URL}/news/feed.atom'

# Determine if we are running in "test" mode e.g. "manage.py test"
TESTING = 'test' in sys.argv or 'TESTING' in os.environ
Expand Down
Loading

0 comments on commit 9f2691a

Please sign in to comment.