CKEditor Migration Successfully Completed

This commit is contained in:
Maximilian 2025-06-07 20:10:08 +02:00
parent 78fadaa1da
commit b860590127
11 changed files with 148 additions and 56 deletions

View file

@ -1,6 +1,6 @@
# Generated by Django 4.2.6 on 2023-10-22 09:59 # Generated by Django 4.2.6 on 2023-10-22 09:59
import ckeditor.fields import django_ckeditor_5.fields
from django.conf import settings from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion import django.db.models.deletion
@ -22,7 +22,7 @@ class Migration(migrations.Migration):
fields=[ fields=[
('id', models.BigAutoField(primary_key=True, serialize=False)), ('id', models.BigAutoField(primary_key=True, serialize=False)),
('name', models.CharField(max_length=256, unique=True, verbose_name='Bezeichnung')), ('name', models.CharField(max_length=256, unique=True, verbose_name='Bezeichnung')),
('description', ckeditor.fields.RichTextField(verbose_name='Erläuterungen')), ('description', django_ckeditor_5.fields.CKEditor5Field(verbose_name='Erläuterungen')),
], ],
options={ options={
'verbose_name': 'Vogel', 'verbose_name': 'Vogel',

View file

@ -1,6 +1,6 @@
# Generated by Django 5.2.2 on 2025-06-07 13:33 # Generated by Django 5.2.2 on 2025-06-07 13:33
import ckeditor.fields import django_ckeditor_5.fields
import django.db.models.deletion import django.db.models.deletion
from django.conf import settings from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
@ -103,6 +103,6 @@ class Migration(migrations.Migration):
migrations.AlterField( migrations.AlterField(
model_name='bird', model_name='bird',
name='description', name='description',
field=ckeditor.fields.RichTextField(blank=True, null=True, verbose_name='Erläuterungen'), field=django_ckeditor_5.fields.CKEditor5Field(blank=True, null=True, verbose_name='Erläuterungen'),
), ),
] ]

View file

@ -0,0 +1,19 @@
# Generated by Django 5.2.2 on 2025-06-07 18:05
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('bird', '0006_alter_fallenbird_options_alter_fallenbird_age_and_more'),
]
operations = [
migrations.AlterField(
model_name='fallenbird',
name='status',
field=models.ForeignKey(blank=True, default=1, null=True, on_delete=django.db.models.deletion.CASCADE, to='bird.birdstatus', verbose_name='Status'),
),
]

View file

@ -5,7 +5,7 @@ from django.conf import settings
from django.db import models from django.db import models
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from ckeditor.fields import RichTextField from django_ckeditor_5.fields import CKEditor5Field
from aviary.models import Aviary from aviary.models import Aviary
@ -125,7 +125,7 @@ class Bird(models.Model):
name = models.CharField( name = models.CharField(
max_length=256, unique=True, verbose_name=_("Bezeichnung") max_length=256, unique=True, verbose_name=_("Bezeichnung")
) )
description = RichTextField(verbose_name=_("Erläuterungen"), blank=True, null=True) description = CKEditor5Field(verbose_name=_("Erläuterungen"), blank=True, null=True)
species = models.CharField( species = models.CharField(
max_length=256, blank=True, null=True, verbose_name=_("Art") max_length=256, blank=True, null=True, verbose_name=_("Art")
) )

View file

@ -6,11 +6,13 @@
SITE_ID = 1 SITE_ID = 1
ACCOUNT_AUTHENTICATION_METHOD = "username_email" # Updated settings to replace deprecated options
ACCOUNT_EMAIL_REQUIRED = True ACCOUNT_LOGIN_METHODS = {"username", "email"} # Replaces ACCOUNT_AUTHENTICATION_METHOD
ACCOUNT_SIGNUP_FIELDS = ["email*", "username*", "password1*", "password2*"] # Replaces ACCOUNT_EMAIL_REQUIRED
ACCOUNT_EMAIL_VERIFICATION = "mandatory" ACCOUNT_EMAIL_VERIFICATION = "mandatory"
ACCOUNT_LOGIN_ATTEMPTS_LIMIT = 5 ACCOUNT_RATE_LIMITS = {
ACCOUNT_LOGIN_ATTEMPTS_TIMEOUT = 900 # 15 Minutes "login_failed": "5/15m", # Replaces ACCOUNT_LOGIN_ATTEMPTS_LIMIT/TIMEOUT (5 attempts per 15 minutes)
}
ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION = True ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION = True
ACCOUNT_LOGOUT_REDIRECT_URL = "/" ACCOUNT_LOGOUT_REDIRECT_URL = "/"
ACCOUNT_LOGOUT_ON_GET = True ACCOUNT_LOGOUT_ON_GET = True

View file

@ -1,15 +1,90 @@
# ----------------------------------- # -----------------------------------
# CKEDITOR CONFIGURATION # CKEDITOR 5 CONFIGURATION
# ----------------------------------- # -----------------------------------
CKEDITOR_BASEPATH = "/static/ckeditor/ckeditor/" customColorPalette = [
CKEDITOR_UPLOAD_PATH = "media" {
'color': 'hsl(4, 90%, 58%)',
'label': 'Red'
},
{
'color': 'hsl(340, 82%, 52%)',
'label': 'Pink'
},
{
'color': 'hsl(291, 64%, 42%)',
'label': 'Purple'
},
{
'color': 'hsl(262, 52%, 47%)',
'label': 'Deep Purple'
},
{
'color': 'hsl(231, 48%, 48%)',
'label': 'Indigo'
},
{
'color': 'hsl(207, 90%, 54%)',
'label': 'Blue'
},
]
CKEDITOR_CONFIGS = { CKEDITOR_5_CONFIGS = {
"default": { 'default': {
"removePlugins": "exportpdf", 'toolbar': ['heading', '|', 'bold', 'italic', 'link',
"height": 300, 'bulletedList', 'numberedList', 'blockQuote', 'imageUpload', ],
"width": "100%",
"allowedContent": True, },
'extends': {
'blockToolbar': [
'paragraph', 'heading1', 'heading2', 'heading3',
'|',
'bulletedList', 'numberedList',
'|',
'blockQuote',
],
'toolbar': ['heading', '|', 'outdent', 'indent', '|', 'bold', 'italic', 'link', 'underline', 'strikethrough',
'code','subscript', 'superscript', 'highlight', '|', 'codeBlock', 'sourceEditing', 'insertImage',
'bulletedList', 'numberedList', 'todoList', '|', 'blockQuote', 'imageUpload', '|',
'fontSize', 'fontFamily', 'fontColor', 'fontBackgroundColor', 'mediaEmbed', 'removeFormat',
'insertTable',],
'image': {
'toolbar': ['imageTextAlternative', '|', 'imageStyle:alignLeft',
'imageStyle:alignRight', 'imageStyle:alignCenter', 'imageStyle:side', ],
'styles': [
'full',
'side',
'alignLeft',
'alignRight',
'alignCenter',
]
},
'table': {
'contentToolbar': [ 'tableColumn', 'tableRow', 'mergeTableCells',
'tableProperties', 'tableCellProperties' ],
'tableProperties': {
'borderColors': customColorPalette,
'backgroundColors': customColorPalette
},
'tableCellProperties': {
'borderColors': customColorPalette,
'backgroundColors': customColorPalette
}
},
'heading' : {
'options': [
{ 'model': 'paragraph', 'title': 'Paragraph', 'class': 'ck-heading_paragraph' },
{ 'model': 'heading1', 'view': 'h1', 'title': 'Heading 1', 'class': 'ck-heading_heading1' },
{ 'model': 'heading2', 'view': 'h2', 'title': 'Heading 2', 'class': 'ck-heading_heading2' },
{ 'model': 'heading3', 'view': 'h3', 'title': 'Heading 3', 'class': 'ck-heading_heading3' }
]
}
},
'list': {
'properties': {
'styles': 'true',
'startIndex': 'true',
'reversed': 'true',
}
} }
} }

View file

@ -5,7 +5,7 @@
CSP_DEFAULT_SRC = ( CSP_DEFAULT_SRC = (
"'self'", "'self'",
"https://cdn.datatables.net", "https://cdn.datatables.net",
"https://cke4.ckeditor.com", "https://cdn.ckeditor.com",
) )
CSP_STYLE_SRC = ( CSP_STYLE_SRC = (
"'self'", "'self'",

View file

@ -74,10 +74,9 @@ INSTALLED_APPS = [
"crispy_bootstrap5", "crispy_bootstrap5",
"crispy_forms", "crispy_forms",
# ----------------------------------- # -----------------------------------
# CKEditor # CKEditor 5
# ----------------------------------- # -----------------------------------
"ckeditor", "django_ckeditor_5",
"ckeditor_uploader",
# ----------------------------------- # -----------------------------------
# My Apps # My Apps
# ----------------------------------- # -----------------------------------
@ -209,11 +208,10 @@ CRISPY_TEMPLATE_PACK = "bootstrap5"
# ----------------------------------- # -----------------------------------
try: try:
from .allauth import ( from .allauth import (
ACCOUNT_AUTHENTICATION_METHOD, ACCOUNT_LOGIN_METHODS,
ACCOUNT_EMAIL_REQUIRED, ACCOUNT_SIGNUP_FIELDS,
ACCOUNT_EMAIL_VERIFICATION, ACCOUNT_EMAIL_VERIFICATION,
ACCOUNT_LOGIN_ATTEMPTS_LIMIT, ACCOUNT_RATE_LIMITS,
ACCOUNT_LOGIN_ATTEMPTS_TIMEOUT,
ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION, ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION,
ACCOUNT_LOGOUT_REDIRECT_URL, ACCOUNT_LOGOUT_REDIRECT_URL,
ACCOUNT_LOGOUT_ON_GET, ACCOUNT_LOGOUT_ON_GET,
@ -262,8 +260,8 @@ try:
except ImportError: except ImportError:
print("No Jazzmin Settings found!") print("No Jazzmin Settings found!")
# CKEditor # CKEditor 5
try: try:
from .ckeditor import CKEDITOR_CONFIGS, CKEDITOR_BASEPATH, CKEDITOR_UPLOAD_PATH from .ckeditor import CKEDITOR_5_CONFIGS
except ImportError: except ImportError:
print("No CKEditor Settings found!") print("No CKEditor Settings found!")

View file

@ -2,7 +2,7 @@ crispy-bootstrap5>=0.6
django-allauth>=0.55 django-allauth>=0.55
django-bootstrap-datepicker-plus>=4.0 django-bootstrap-datepicker-plus>=4.0
django-bootstrap-modal-forms>=2 django-bootstrap-modal-forms>=2
django-ckeditor>=6.6 django-ckeditor-5>=0.2
django-crispy-forms>=1 django-crispy-forms>=1
django-csp>=3.7 django-csp>=3.7
django-environ>=0.9 django-environ>=0.9

View file

@ -39,8 +39,7 @@ THIRD_PARTY_APPS = [
'allauth.account', 'allauth.account',
'bootstrap_datepicker_plus', 'bootstrap_datepicker_plus',
'bootstrap_modal_forms', 'bootstrap_modal_forms',
'ckeditor', 'django_ckeditor_5',
'ckeditor_uploader',
] ]
# Local apps # Local apps
@ -151,11 +150,10 @@ LOGOUT_REDIRECT_URL = '/'
CRISPY_ALLOWED_TEMPLATE_PACKS = 'bootstrap5' CRISPY_ALLOWED_TEMPLATE_PACKS = 'bootstrap5'
CRISPY_TEMPLATE_PACK = 'bootstrap5' CRISPY_TEMPLATE_PACK = 'bootstrap5'
# CKEditor settings for tests # CKEditor 5 settings for tests
CKEDITOR_UPLOAD_PATH = tempfile.mkdtemp() CKEDITOR_5_CONFIGS = {
CKEDITOR_CONFIGS = {
'default': { 'default': {
'toolbar': 'Basic', 'toolbar': ['bold', 'italic', 'underline', '|', 'bulletedList', 'numberedList'],
}, },
} }

View file

@ -11,14 +11,17 @@ Dieses Dokument listet alle Abhängigkeiten auf, die Updates benötigen, sowie S
## 🚨 Kritische Sicherheitsupdates ## 🚨 Kritische Sicherheitsupdates
### 1. CKEditor (HOCH PRIORITÄT) ### 1. CKEditor (HOCH PRIORITÄT) ✅ ABGESCHLOSSEN
- **Aktuell:** django-ckeditor 6.7.3 (bündelt CKEditor 4.22.1) - **Früher:** django-ckeditor 6.7.3 (bündelte CKEditor 4.22.1)
- **Problem:** CKEditor 4.22.1 wird nicht mehr unterstützt und hat bekannte Sicherheitslücken - **Problem:** CKEditor 4.22.1 war nicht mehr unterstützt und hatte bekannte Sicherheitslücken
- **Empfehlung:** Migration zu CKEditor 5 oder einem alternativen Editor - **Lösung:** ✅ Migration zu CKEditor 5 abgeschlossen
- **Alternativen:** - **Implementiert:**
- `django-ckeditor-5` (falls CKEditor 5 Lizenz akzeptabel) - ✅ `django-ckeditor-5==0.2.18` installiert
- `django-tinymce` (Alternative Rich Text Editor) - ✅ Alle Django Settings auf CKEditor 5 umgestellt
- `django-froala-editor` (kommerzielle Alternative) - ✅ CSP Settings für CKEditor 5 CDN aktualisiert
- ✅ Migration Files korrigiert und Datenbank migriert
- ✅ Alle Tests erfolgreich (keine Deprecated Warnings)
- ✅ Web-Interface funktioniert korrekt mit CKEditor 5
### 2. Django-allauth Settings (MITTEL PRIORITÄT) ### 2. Django-allauth Settings (MITTEL PRIORITÄT)
- **Problem:** Veraltete Settings-Optionen werden verwendet - **Problem:** Veraltete Settings-Optionen werden verwendet
@ -99,19 +102,16 @@ Dieses Dokument listet alle Abhängigkeiten auf, die Updates benötigen, sowie S
## 🛠️ Empfohlene Update-Reihenfolge ## 🛠️ Empfohlene Update-Reihenfolge
### Phase 1: Kritische Sicherheitsupdates (Sofort) ### Phase 1: Kritische Sicherheitsupdates ✅ ABGESCHLOSSEN
1. **CKEditor ersetzen** 1. **CKEditor Migration** ✅ **ABGESCHLOSSEN**
```bash - ✅ django-ckeditor-5==0.2.18 installiert
# Option 1: django-ckeditor-5 verwenden - ✅ Django Settings komplett umgestellt
pip uninstall django-ckeditor - ✅ Migration Files korrigiert
pip install django-ckeditor-5 - ✅ Datenbank erfolgreich migriert
- ✅ CSP Security Policy aktualisiert
# Option 2: TinyMCE verwenden - ✅ Web-Interface getestet und funktionsfähig
pip uninstall django-ckeditor
pip install django-tinymce
```
2. **Django-allauth Settings aktualisieren** 2. **Django-allauth Settings aktualisieren** 🟡 **NOCH OFFEN**
- Settings in `core/settings.py` anpassen - Settings in `core/settings.py` anpassen
- Deprecated Warnings beheben - Deprecated Warnings beheben