Skip to content

Commit 4dcfc08

Browse files
committed
Add config EMBED_HOSTNAME_ALLOWED
1 parent 53b8a85 commit 4dcfc08

File tree

5 files changed

+75
-11
lines changed

5 files changed

+75
-11
lines changed

README.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -293,15 +293,16 @@ plugin use css property [prefers-color-scheme](https://developer.mozilla.org/en-
293293
The application can be configured by editing the project's `settings.py`
294294
file.
295295

296-
| Key | Description | Default | Type |
297-
| --------------------------------- | ---------------------------------------------------------------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------ |
298-
| `EDITORJS_DEFAULT_PLUGINS` | List of plugins names Editor.js from npm | [See above](#plugins) | `list[str]`, `tuple[str]` |
299-
| `EDITORJS_DEFAULT_CONFIG_TOOLS` | Map of Tools to use | [See above](#plugins) | `dict[str, dict]` |
300-
| `EDITORJS_IMAGE_UPLOAD_PATH` | Path uploads images | `uploads/images/` | `str` |
301-
| `EDITORJS_IMAGE_UPLOAD_PATH_DATE` | Subdirectories | `%Y/%m/` | `str` |
302-
| `EDITORJS_IMAGE_NAME_ORIGINAL` | To use the original name of the image file? | `False` | `bool` |
303-
| `EDITORJS_IMAGE_NAME` | Image file name. Ignored when `EDITORJS_IMAGE_NAME_ORIGINAL` is `True` | `token_urlsafe(8)` | `callable(filename: str, file: InMemoryUploadedFile)` ([docs](https://docs.djangoproject.com/en/3.0/ref/files/uploads/)) |
304-
| `EDITORJS_VERSION` | Version Editor.js | `2.22.3` | `str` |
296+
| Key | Description | Default | Type |
297+
| --------------------------------- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
298+
| `EDITORJS_DEFAULT_PLUGINS` | List of plugins names Editor.js from npm | [See above](#plugins) | `list[str]`, `tuple[str]` |
299+
| `EDITORJS_DEFAULT_CONFIG_TOOLS` | Map of Tools to use | [See above](#plugins) | `dict[str, dict]` |
300+
| `EDITORJS_IMAGE_UPLOAD_PATH` | Path uploads images | `uploads/images/` | `str` |
301+
| `EDITORJS_IMAGE_UPLOAD_PATH_DATE` | Subdirectories | `%Y/%m/` | `str` |
302+
| `EDITORJS_IMAGE_NAME_ORIGINAL` | To use the original name of the image file? | `False` | `bool` |
303+
| `EDITORJS_IMAGE_NAME` | Image file name. Ignored when `EDITORJS_IMAGE_NAME_ORIGINAL` is `True` | `token_urlsafe(8)` | `callable(filename: str, file: InMemoryUploadedFile)` ([docs](https://docs.djangoproject.com/en/3.0/ref/files/uploads/)) |
304+
| `EDITORJS_EMBED_HOSTNAME_ALLOWED` | List of allowed hostname for embed | `('player.vimeo.com','www.youtube.com','coub.com','vine.co','imgur.com','gfycat.com','player.twitch.tv','player.twitch.tv','music.yandex.ru','codepen.io','www.instagram.com','twitframe.com','assets.pinterest.com','www.facebook.com','www.aparat.com'),` | `list[str]`, `tuple[str]` |
305+
| `EDITORJS_VERSION` | Version Editor.js | `2.22.3` | `str` |
305306

306307
For `EDITORJS_IMAGE_NAME` was used `from secrets import token_urlsafe`
307308

django_editorjs_fields/config.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,30 @@
77

88
VERSION = getattr(settings, "EDITORJS_VERSION", '2.22.2')
99

10+
# ATTACHMENT_REQUIRE_AUTHENTICATION = str(
11+
# getattr(settings, "EDITORJS_ATTACHMENT_REQUIRE_AUTHENTICATION", True)
12+
# )
13+
14+
EMBED_HOSTNAME_ALLOWED = str(
15+
getattr(settings, "EDITORJS_EMBED_HOSTNAME_ALLOWED", (
16+
'player.vimeo.com',
17+
'www.youtube.com',
18+
'coub.com',
19+
'vine.co',
20+
'imgur.com',
21+
'gfycat.com',
22+
'player.twitch.tv',
23+
'player.twitch.tv',
24+
'music.yandex.ru',
25+
'codepen.io',
26+
'www.instagram.com',
27+
'twitframe.com',
28+
'assets.pinterest.com',
29+
'www.facebook.com',
30+
'www.aparat.com',
31+
))
32+
)
33+
1034
IMAGE_UPLOAD_PATH = str(
1135
getattr(settings, "EDITORJS_IMAGE_UPLOAD_PATH", 'uploads/images/')
1236
)

django_editorjs_fields/fields.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1+
import json
2+
13
from django.core import checks
4+
from django.core.exceptions import ValidationError
25
from django.db.models import Field
36
from django.forms import Textarea
47

5-
from .config import DEBUG
8+
from .config import DEBUG, EMBED_HOSTNAME_ALLOWED
9+
from .utils import get_hostname_from_url
610
from .widgets import EditorJsWidget
711

812
try:
@@ -51,6 +55,34 @@ def __init__(self, plugins, tools, **kwargs):
5155

5256
super().__init__(**kwargs)
5357

58+
def validate_embed(self, value):
59+
for item in value.get('blocks', []):
60+
type = item.get('type', '').lower()
61+
if type == 'embed':
62+
embed = item['data']['embed']
63+
hostname = get_hostname_from_url(embed)
64+
65+
if hostname not in EMBED_HOSTNAME_ALLOWED:
66+
raise ValidationError(
67+
hostname + ' is not allowed in EDITORJS_EMBED_HOSTNAME_ALLOWED')
68+
69+
def clean(self, value, model_instance):
70+
if value and value != 'null':
71+
if not isinstance(value, dict):
72+
try:
73+
value = json.loads(value)
74+
except ValueError:
75+
pass
76+
except TypeError:
77+
pass
78+
else:
79+
self.validate_embed(value)
80+
value = json.dumps(value)
81+
else:
82+
self.validate_embed(value)
83+
84+
return super().clean(value, model_instance)
85+
5486
def formfield(self, **kwargs):
5587
if self.use_editorjs:
5688
kwargs['widget'] = EditorJsWidget(

django_editorjs_fields/utils.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import urllib.parse
2+
13
from django.conf import settings
24
from django.utils.module_loading import import_string
35

@@ -12,4 +14,9 @@ def get_storage_class():
1214
)()
1315

1416

17+
def get_hostname_from_url(url):
18+
obj_url = urllib.parse.urlsplit(url)
19+
return obj_url.hostname
20+
21+
1522
storage = get_storage_class()

example/blog/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class Post(models.Model):
4646
blank=True,
4747
)
4848
body_textfield = EditorJsTextField( # only images and paragraph (default)
49-
plugins=["@editorjs/image"], null=True, blank=True,
49+
plugins=["@editorjs/image", "@editorjs/embed"], null=True, blank=True,
5050
i18n={
5151
'messages': {
5252
'blockTunes': {

0 commit comments

Comments
 (0)