Compare commits
5 Commits
feature/nf
...
5535684a45
| Author | SHA1 | Date | |
|---|---|---|---|
| 5535684a45 | |||
| f933b7d99a | |||
| fd729b3019 | |||
| e1c1eafb39 | |||
| 1b016c49f2 |
241
Documentation/ArgoCD.md
Normal file
241
Documentation/ArgoCD.md
Normal file
@@ -0,0 +1,241 @@
|
|||||||
|
# ArgoCD Configuration Documentation
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
This directory contains the ArgoCD application manifests for deploying the VorgabenUI application and its dependencies to Kubernetes.
|
||||||
|
|
||||||
|
## Files
|
||||||
|
|
||||||
|
### Application Manifests
|
||||||
|
|
||||||
|
#### `001_pvc.yaml`
|
||||||
|
- **Purpose**: PersistentVolumeClaim for Django application data
|
||||||
|
- **Storage**: 2Gi storage with ReadWriteMany access mode
|
||||||
|
- **Storage Class**: Uses NFS storage class for shared storage across multiple pods
|
||||||
|
- **Namespace**: vorgabenui
|
||||||
|
|
||||||
|
#### `deployment.yaml`
|
||||||
|
- **Purpose**: Main application deployment configuration
|
||||||
|
- **Contains**: Django application container, environment variables, resource limits
|
||||||
|
- **Replicas**: Configurable replica count for high availability
|
||||||
|
|
||||||
|
#### `ingress.yaml`
|
||||||
|
- **Purpose**: External access configuration
|
||||||
|
- **Host**: Configurable hostname for the application
|
||||||
|
- **TLS**: SSL/TLS termination configuration
|
||||||
|
- **Backend**: Routes traffic to the Django application service
|
||||||
|
|
||||||
|
#### `nfs-pv.yaml`
|
||||||
|
- **Purpose**: PersistentVolume definition for NFS storage
|
||||||
|
- **Server**: 192.168.17.199
|
||||||
|
- **Path**: /mnt/user/vorgabenui
|
||||||
|
- **Access**: ReadWriteMany for multi-pod access
|
||||||
|
- **Reclaim Policy**: Retain (data preserved after PVC deletion)
|
||||||
|
|
||||||
|
#### `nfs-storageclass.yaml`
|
||||||
|
- **Purpose**: StorageClass definition for NFS volumes
|
||||||
|
- **Provisioner**: kubernetes.io/no-provisioner (static provisioning)
|
||||||
|
- **Volume Expansion**: Enabled for growing storage capacity
|
||||||
|
- **Binding Mode**: Immediate (binds PV to PVC as soon as possible)
|
||||||
|
|
||||||
|
#### `diagrammer.yaml`
|
||||||
|
- **Purpose**: Deployment configuration for the diagram generation service
|
||||||
|
- **Function**: Handles diagram creation and caching for the application
|
||||||
|
|
||||||
|
## NFS Storage Configuration
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
1. NFS server must be running at 192.168.17.199
|
||||||
|
2. The directory `/mnt/user/vorgabenui` must exist and be exported
|
||||||
|
3. Kubernetes nodes must have NFS client utilities installed
|
||||||
|
4. For MicroK8s: `microk8s enable nfs`
|
||||||
|
|
||||||
|
## MicroK8s Addons Required
|
||||||
|
|
||||||
|
### Required Addons
|
||||||
|
Enable the following MicroK8s addons before deployment:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Enable storage and NFS support
|
||||||
|
sudo microk8s enable storage
|
||||||
|
sudo microk8s enable nfs
|
||||||
|
|
||||||
|
# Enable ingress for external access
|
||||||
|
sudo microk8s enable ingress
|
||||||
|
|
||||||
|
# Enable DNS for service discovery
|
||||||
|
sudo microk8s enable dns
|
||||||
|
|
||||||
|
# Optional: Enable metrics for monitoring
|
||||||
|
sudo microk8s enable metrics-server
|
||||||
|
```
|
||||||
|
|
||||||
|
### Addon Descriptions
|
||||||
|
|
||||||
|
#### `storage`
|
||||||
|
- **Purpose**: Provides default storage class for persistent volumes
|
||||||
|
- **Required for**: Basic PVC functionality
|
||||||
|
- **Note**: Works alongside our custom NFS storage class
|
||||||
|
|
||||||
|
#### `nfs`
|
||||||
|
- **Purpose**: Installs NFS client utilities on all MicroK8s nodes
|
||||||
|
- **Required for**: Mounting NFS volumes in pods
|
||||||
|
- **Components**: Installs `nfs-common` package with mount helpers
|
||||||
|
|
||||||
|
#### `ingress`
|
||||||
|
- **Purpose**: Provides Ingress controller for external HTTP/HTTPS access
|
||||||
|
- **Required for**: `ingress.yaml` to function properly
|
||||||
|
- **Implementation**: Uses NGINX Ingress Controller
|
||||||
|
|
||||||
|
#### `dns`
|
||||||
|
- **Purpose**: Provides DNS service for service discovery within cluster
|
||||||
|
- **Required for**: Inter-service communication
|
||||||
|
- **Note**: Usually enabled by default in MicroK8s
|
||||||
|
|
||||||
|
#### `metrics-server` (Optional)
|
||||||
|
- **Purpose**: Enables resource usage monitoring
|
||||||
|
- **Required for**: `kubectl top` commands and HPA (Horizontal Pod Autoscaling)
|
||||||
|
- **Recommended for**: Production monitoring
|
||||||
|
|
||||||
|
### Addon Verification
|
||||||
|
After enabling addons, verify they are running:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check addon status
|
||||||
|
microk8s status
|
||||||
|
|
||||||
|
# Check pods in kube-system namespace
|
||||||
|
microk8s kubectl get pods -n kube-system
|
||||||
|
|
||||||
|
# Check storage classes
|
||||||
|
microk8s kubectl get storageclass
|
||||||
|
|
||||||
|
# Check ingress controller
|
||||||
|
microk8s kubectl get pods -n ingress
|
||||||
|
```
|
||||||
|
|
||||||
|
### Troubleshooting Addons
|
||||||
|
|
||||||
|
#### NFS Addon Issues
|
||||||
|
```bash
|
||||||
|
# Check if NFS utilities are installed
|
||||||
|
which mount.nfs
|
||||||
|
|
||||||
|
# Manually install if addon fails
|
||||||
|
sudo apt update && sudo apt install nfs-common
|
||||||
|
|
||||||
|
# Restart MicroK8s after manual installation
|
||||||
|
sudo microk8s restart
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Ingress Issues
|
||||||
|
```bash
|
||||||
|
# Check ingress controller pods
|
||||||
|
microk8s kubectl get pods -n ingress
|
||||||
|
|
||||||
|
# Check ingress services
|
||||||
|
microk8s kubectl get svc -n ingress
|
||||||
|
|
||||||
|
# Test ingress connectivity
|
||||||
|
curl -k https://your-domain.com
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Storage Issues
|
||||||
|
```bash
|
||||||
|
# List available storage classes
|
||||||
|
microk8s kubectl get storageclass
|
||||||
|
|
||||||
|
# Check default storage class
|
||||||
|
microk8s kubectl get storageclass -o yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
### Storage Architecture
|
||||||
|
- **Storage Class**: `nfs` - Static provisioning for NFS shares
|
||||||
|
- **Persistent Volume**: Pre-provisioned PV pointing to NFS server
|
||||||
|
- **Persistent Volume Claim**: Claims the NFS storage for application use
|
||||||
|
- **Access Mode**: ReadWriteMany allows multiple pods to access the same data
|
||||||
|
|
||||||
|
### NFS Server Setup
|
||||||
|
On the NFS server (192.168.17.199), ensure the following:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create the shared directory
|
||||||
|
sudo mkdir -p /mnt/user/vorgabenui
|
||||||
|
sudo chmod 755 /mnt/user/vorgabenui
|
||||||
|
|
||||||
|
# Add to /etc/exports
|
||||||
|
echo "/mnt/user/vorgabenui *(rw,sync,no_subtree_check,no_root_squash)" | sudo tee -a /etc/exports
|
||||||
|
|
||||||
|
# Export the directory
|
||||||
|
sudo exportfs -a
|
||||||
|
sudo systemctl restart nfs-kernel-server
|
||||||
|
```
|
||||||
|
|
||||||
|
## Deployment Order
|
||||||
|
|
||||||
|
1. **StorageClass** (`nfs-storageclass.yaml`) - Defines NFS storage class
|
||||||
|
2. **PersistentVolume** (`nfs-pv.yaml`) - Creates the NFS volume
|
||||||
|
3. **PersistentVolumeClaim** (`001_pvc.yaml`) - Claims storage for application
|
||||||
|
4. **Application Deployments** (`deployment.yaml`, `diagrammer.yaml`) - Deploy application services
|
||||||
|
5. **Ingress** (`ingress.yaml`) - Configure external access
|
||||||
|
|
||||||
|
## Configuration Notes
|
||||||
|
|
||||||
|
### Namespace
|
||||||
|
All resources are deployed to the `vorgabenui` namespace.
|
||||||
|
|
||||||
|
### Storage Sizing
|
||||||
|
- Current allocation: 2Gi
|
||||||
|
- Volume expansion is enabled through the StorageClass
|
||||||
|
- Monitor usage and adjust PVC size as needed
|
||||||
|
|
||||||
|
### Access Control
|
||||||
|
- NFS export uses `no_root_squash` for container root access
|
||||||
|
- Ensure proper network security between Kubernetes nodes and NFS server
|
||||||
|
- Consider implementing network policies for additional security
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
#### Mount Failures
|
||||||
|
- **Error**: "bad option; for several filesystems you might need a /sbin/mount.<type> helper program"
|
||||||
|
- **Solution**: Install NFS client utilities or enable NFS addon in MicroK8s
|
||||||
|
|
||||||
|
#### Permission Issues
|
||||||
|
- **Error**: Permission denied when accessing mounted volume
|
||||||
|
- **Solution**: Check NFS export permissions and ensure `no_root_squash` is set
|
||||||
|
|
||||||
|
#### Network Connectivity
|
||||||
|
- **Error**: Connection timeout to NFS server
|
||||||
|
- **Solution**: Verify network connectivity and firewall rules between nodes and NFS server
|
||||||
|
|
||||||
|
### Debug Commands
|
||||||
|
```bash
|
||||||
|
# Check PVC status
|
||||||
|
kubectl get pvc -n vorgabenui
|
||||||
|
|
||||||
|
# Check PV status
|
||||||
|
kubectl get pv
|
||||||
|
|
||||||
|
# Describe PVC for detailed information
|
||||||
|
kubectl describe pvc django-data-pvc -n vorgabenui
|
||||||
|
|
||||||
|
# Check pod mount status
|
||||||
|
kubectl describe pod <pod-name> -n vorgabenui
|
||||||
|
```
|
||||||
|
|
||||||
|
## Maintenance
|
||||||
|
|
||||||
|
### Backup Strategy
|
||||||
|
- The NFS server should have regular backups of `/mnt/user/vorgabenui`
|
||||||
|
- Consider snapshot capabilities if using enterprise NFS solutions
|
||||||
|
|
||||||
|
### Monitoring
|
||||||
|
- Monitor NFS server performance and connectivity
|
||||||
|
- Track storage usage and plan capacity upgrades
|
||||||
|
- Monitor pod restarts related to storage issues
|
||||||
|
|
||||||
|
### Updates
|
||||||
|
- When updating storage configuration, update PV first, then PVC
|
||||||
|
- Test changes in non-production environment first
|
||||||
|
- Ensure backward compatibility when modifying NFS exports
|
||||||
@@ -15,7 +15,7 @@ Dieses Dokument bietet einen umfassenden Überblick über alle Tests im vgui-cic
|
|||||||
|
|
||||||
## abschnitte App Tests
|
## abschnitte App Tests
|
||||||
|
|
||||||
Die abschnitte App enthält 32 Tests, die Modelle, Utility-Funktionen, Diagram-Caching und Management-Befehle abdecken.
|
Die abschnitte App enthält 33 Tests, die Modelle, Utility-Funktionen, Diagram-Caching, Management-Befehle und Sicherheit abdecken.
|
||||||
|
|
||||||
### Modell-Tests
|
### Modell-Tests
|
||||||
|
|
||||||
@@ -58,6 +58,7 @@ Die abschnitte App enthält 32 Tests, die Modelle, Utility-Funktionen, Diagram-C
|
|||||||
- **test_render_text_with_footnotes**: Verarbeitet Text, der Fußnoten enthält
|
- **test_render_text_with_footnotes**: Verarbeitet Text, der Fußnoten enthält
|
||||||
- **test_render_abschnitt_without_type**: Behandelt Textabschnitte ohne AbschnittTyp
|
- **test_render_abschnitt_without_type**: Behandelt Textabschnitte ohne AbschnittTyp
|
||||||
- **test_render_abschnitt_with_empty_content**: Behandelt Textabschnitte mit leerem Inhalt
|
- **test_render_abschnitt_with_empty_content**: Behandelt Textabschnitte mit leerem Inhalt
|
||||||
|
- **test_render_textabschnitte_xss_prevention**: Überprüft, dass bösartiger HTML-Code und Skript-Tags aus gerenderten Inhalten bereinigt werden, um XSS-Angriffe zu verhindern
|
||||||
|
|
||||||
### Diagram-Caching-Tests
|
### Diagram-Caching-Tests
|
||||||
|
|
||||||
@@ -332,8 +333,8 @@ Die stichworte App enthält 18 Tests, die Schlüsselwortmodelle und ihre Sortier
|
|||||||
|
|
||||||
## Test-Statistiken
|
## Test-Statistiken
|
||||||
|
|
||||||
- **Gesamt-Tests**: 206
|
- **Gesamt-Tests**: 207
|
||||||
- **abschnitte**: 32 Tests
|
- **abschnitte**: 33 Tests (einschließlich XSS-Prävention)
|
||||||
- **dokumente**: 116 Tests (98 in tests.py + 9 in test_json.py + 9 JSON-Tests in Haupt-tests.py)
|
- **dokumente**: 116 Tests (98 in tests.py + 9 in test_json.py + 9 JSON-Tests in Haupt-tests.py)
|
||||||
- **pages**: 4 Tests
|
- **pages**: 4 Tests
|
||||||
- **referenzen**: 18 Tests
|
- **referenzen**: 18 Tests
|
||||||
@@ -348,6 +349,7 @@ Die stichworte App enthält 18 Tests, die Schlüsselwortmodelle und ihre Sortier
|
|||||||
4. **Utility-Funktionen**: Textverarbeitung, Caching, Formatierung
|
4. **Utility-Funktionen**: Textverarbeitung, Caching, Formatierung
|
||||||
5. **Management-Befehle**: CLI-Schnittstelle und Ausgabeverarbeitung
|
5. **Management-Befehle**: CLI-Schnittstelle und Ausgabeverarbeitung
|
||||||
6. **Integration**: App-übergreifende Funktionalität und Datenfluss
|
6. **Integration**: App-übergreifende Funktionalität und Datenfluss
|
||||||
|
7. **Sicherheit**: XSS-Prävention durch HTML-Bereinigung beim Rendern von Inhalten
|
||||||
|
|
||||||
## Ausführen der Tests
|
## Ausführen der Tests
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ This document provides a comprehensive overview of all tests in the vgui-cicd Dj
|
|||||||
|
|
||||||
## abschnitte App Tests
|
## abschnitte App Tests
|
||||||
|
|
||||||
The abschnitte app contains 32 tests covering models, utility functions, diagram caching, and management commands.
|
The abschnitte app contains 33 tests covering models, utility functions, diagram caching, management commands, and security.
|
||||||
|
|
||||||
### Model Tests
|
### Model Tests
|
||||||
|
|
||||||
@@ -58,6 +58,7 @@ The abschnitte app contains 32 tests covering models, utility functions, diagram
|
|||||||
- **test_render_text_with_footnotes**: Processes text containing footnotes
|
- **test_render_text_with_footnotes**: Processes text containing footnotes
|
||||||
- **test_render_abschnitt_without_type**: Handles Textabschnitte without AbschnittTyp
|
- **test_render_abschnitt_without_type**: Handles Textabschnitte without AbschnittTyp
|
||||||
- **test_render_abschnitt_with_empty_content**: Handles Textabschnitte with empty content
|
- **test_render_abschnitt_with_empty_content**: Handles Textabschnitte with empty content
|
||||||
|
- **test_render_textabschnitte_xss_prevention**: Verifies that malicious HTML and script tags are sanitized from rendered content to prevent XSS attacks
|
||||||
|
|
||||||
### Diagram Caching Tests
|
### Diagram Caching Tests
|
||||||
|
|
||||||
@@ -332,8 +333,8 @@ The stichworte app contains 18 tests covering keyword models and their ordering.
|
|||||||
|
|
||||||
## Test Statistics
|
## Test Statistics
|
||||||
|
|
||||||
- **Total Tests**: 206
|
- **Total Tests**: 207
|
||||||
- **abschnitte**: 32 tests
|
- **abschnitte**: 33 tests (including XSS prevention)
|
||||||
- **dokumente**: 116 tests (98 in tests.py + 9 in test_json.py + 9 JSON tests in main tests.py)
|
- **dokumente**: 116 tests (98 in tests.py + 9 in test_json.py + 9 JSON tests in main tests.py)
|
||||||
- **pages**: 4 tests
|
- **pages**: 4 tests
|
||||||
- **referenzen**: 18 tests
|
- **referenzen**: 18 tests
|
||||||
@@ -348,6 +349,7 @@ The stichworte app contains 18 tests covering keyword models and their ordering.
|
|||||||
4. **Utility Functions**: Text processing, caching, formatting
|
4. **Utility Functions**: Text processing, caching, formatting
|
||||||
5. **Management Commands**: CLI interface and output handling
|
5. **Management Commands**: CLI interface and output handling
|
||||||
6. **Integration**: Cross-app functionality and data flow
|
6. **Integration**: Cross-app functionality and data flow
|
||||||
|
7. **Security**: XSS prevention through HTML sanitization in content rendering
|
||||||
|
|
||||||
## Running the Tests
|
## Running the Tests
|
||||||
|
|
||||||
|
|||||||
@@ -28,12 +28,6 @@ DEBUG = True
|
|||||||
|
|
||||||
ALLOWED_HOSTS = ["10.128.128.144","localhost","127.0.0.1","*"]
|
ALLOWED_HOSTS = ["10.128.128.144","localhost","127.0.0.1","*"]
|
||||||
|
|
||||||
TEMPLATES = [
|
|
||||||
{"BACKEND": "django.template.backends.django.DjangoTemplates",
|
|
||||||
"APP_DIRS": True,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
# Application definition
|
# Application definition
|
||||||
|
|
||||||
INSTALLED_APPS = [
|
INSTALLED_APPS = [
|
||||||
|
|||||||
@@ -467,6 +467,32 @@ A -> B
|
|||||||
typ, html = result[0]
|
typ, html = result[0]
|
||||||
self.assertEqual(typ, "text")
|
self.assertEqual(typ, "text")
|
||||||
|
|
||||||
|
def test_render_textabschnitte_xss_prevention(self):
|
||||||
|
"""Test that malicious HTML is sanitized in rendered content"""
|
||||||
|
from dokumente.models import VorgabeLangtext
|
||||||
|
|
||||||
|
# Create content with malicious HTML
|
||||||
|
malicious_abschnitt = VorgabeLangtext.objects.create(
|
||||||
|
abschnitt=self.vorgabe,
|
||||||
|
abschnitttyp=self.typ_text,
|
||||||
|
inhalt='<script>alert("xss")</script><img src=x onerror=alert(1)>Normal text',
|
||||||
|
order=1
|
||||||
|
)
|
||||||
|
|
||||||
|
result = render_textabschnitte(VorgabeLangtext.objects.filter(pk=malicious_abschnitt.pk))
|
||||||
|
|
||||||
|
self.assertEqual(len(result), 1)
|
||||||
|
typ, html = result[0]
|
||||||
|
self.assertEqual(typ, "text")
|
||||||
|
|
||||||
|
# Dangerous tags and attributes should be removed or sanitized
|
||||||
|
self.assertNotIn('<script>', html) # Script tags should not be present unescaped
|
||||||
|
self.assertNotIn('onerror', html) # Dangerous attributes removed
|
||||||
|
# Note: 'alert' may still be present in escaped script tags, which is safe
|
||||||
|
|
||||||
|
# Safe content should remain
|
||||||
|
self.assertIn('Normal text', html)
|
||||||
|
|
||||||
|
|
||||||
class MdTableToHtmlTest(TestCase):
|
class MdTableToHtmlTest(TestCase):
|
||||||
"""Test cases for md_table_to_html function"""
|
"""Test cases for md_table_to_html function"""
|
||||||
|
|||||||
@@ -4,12 +4,34 @@ import zlib
|
|||||||
import re
|
import re
|
||||||
from textwrap import dedent
|
from textwrap import dedent
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
import bleach
|
||||||
|
|
||||||
# Import the caching function
|
# Import the caching function
|
||||||
from diagramm_proxy.diagram_cache import get_cached_diagram
|
from diagramm_proxy.diagram_cache import get_cached_diagram
|
||||||
|
|
||||||
DIAGRAMMSERVER="/diagramm"
|
DIAGRAMMSERVER="/diagramm"
|
||||||
|
|
||||||
|
# Allowed HTML tags for bleach sanitization
|
||||||
|
ALLOWED_TAGS = [
|
||||||
|
'p', 'br', 'strong', 'em', 'u', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
|
||||||
|
'ul', 'ol', 'li', 'blockquote', 'code', 'pre', 'hr',
|
||||||
|
'table', 'thead', 'tbody', 'tr', 'th', 'td',
|
||||||
|
'img', 'a', 'sup', 'sub', 'span', 'div'
|
||||||
|
]
|
||||||
|
|
||||||
|
ALLOWED_ATTRIBUTES = {
|
||||||
|
'img': ['src', 'alt', 'width', 'height'],
|
||||||
|
'a': ['href', 'title'],
|
||||||
|
'span': ['class'],
|
||||||
|
'div': ['class'],
|
||||||
|
'p': ['class'],
|
||||||
|
'table': ['class'],
|
||||||
|
'th': ['colspan', 'rowspan', 'class'],
|
||||||
|
'td': ['colspan', 'rowspan', 'class'],
|
||||||
|
'pre': ['class'],
|
||||||
|
'code': ['class'],
|
||||||
|
}
|
||||||
|
|
||||||
def render_textabschnitte(queryset):
|
def render_textabschnitte(queryset):
|
||||||
"""
|
"""
|
||||||
Converts a queryset of Textabschnitt-like models into a list of (typ, html) tuples.
|
Converts a queryset of Textabschnitt-like models into a list of (typ, html) tuples.
|
||||||
@@ -52,6 +74,8 @@ def render_textabschnitte(queryset):
|
|||||||
html += "</code></pre>"
|
html += "</code></pre>"
|
||||||
else:
|
else:
|
||||||
html = markdown(inhalt, extensions=['tables', 'attr_list','footnotes'])
|
html = markdown(inhalt, extensions=['tables', 'attr_list','footnotes'])
|
||||||
|
# Sanitize HTML to prevent XSS
|
||||||
|
html = bleach.clean(html, tags=ALLOWED_TAGS, attributes=ALLOWED_ATTRIBUTES)
|
||||||
output.append((typ, html))
|
output.append((typ, html))
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ spec:
|
|||||||
mountPath: /data
|
mountPath: /data
|
||||||
containers:
|
containers:
|
||||||
- name: web
|
- name: web
|
||||||
image: git.baumann.gr/adebaumann/vui:0.957
|
image: git.baumann.gr/adebaumann/vui:0.957-xss
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 8000
|
- containerPort: 8000
|
||||||
|
|||||||
@@ -102,6 +102,7 @@
|
|||||||
<li><a href="/dokumente">Standards</a></li>
|
<li><a href="/dokumente">Standards</a></li>
|
||||||
{% if user.is_staff %}
|
{% if user.is_staff %}
|
||||||
<li><a href="/dokumente/unvollstaendig/">Unvollständig</a></li>
|
<li><a href="/dokumente/unvollstaendig/">Unvollständig</a></li>
|
||||||
|
<li><a href="/autorenumgebung/">Autorenumgebung</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<li><a href="/referenzen">Referenzen</a></li>
|
<li><a href="/referenzen">Referenzen</a></li>
|
||||||
<li><a href="/stichworte">Stichworte</a></li>
|
<li><a href="/stichworte">Stichworte</a></li>
|
||||||
@@ -131,6 +132,9 @@
|
|||||||
<li class="dropdown {% if 'unvollstaendig' in request.path %}current{% endif %}">
|
<li class="dropdown {% if 'unvollstaendig' in request.path %}current{% endif %}">
|
||||||
<a href="/dokumente/unvollstaendig/">Unvollständig</a>
|
<a href="/dokumente/unvollstaendig/">Unvollständig</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="dropdown {% if 'autorenumgebung' in request.path %}current{% endif %}">
|
||||||
|
<a href="/autorenumgebung/">Autorenumgebung</a>
|
||||||
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<li class="dropdown {% if 'referenzen' in request.path %}current{% endif %}">
|
<li class="dropdown {% if 'referenzen' in request.path %}current{% endif %}">
|
||||||
<a href="/referenzen">Referenzen</a>
|
<a href="/referenzen">Referenzen</a>
|
||||||
@@ -211,7 +215,7 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6 text-right">
|
<div class="col-sm-6 text-right">
|
||||||
<p class="text-muted">Version {{ version|default:"0.957" }}</p>
|
<p class="text-muted">Version {{ version|default:"0.957-xss" }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -32,3 +32,4 @@ six==1.17.0
|
|||||||
sqlparse==0.5.3
|
sqlparse==0.5.3
|
||||||
urllib3==2.5.0
|
urllib3==2.5.0
|
||||||
wcwidth==0.2.13
|
wcwidth==0.2.13
|
||||||
|
bleach==6.1.0
|
||||||
|
|||||||
Reference in New Issue
Block a user