added CORS middleware

This commit is contained in:
smilerz 2021-03-28 18:39:20 -05:00
parent 9a62b6e4e7
commit a341fd8ebe
9 changed files with 62 additions and 36 deletions

View File

@ -229,6 +229,7 @@ class BookmarkletImportAdmin(admin.ModelAdmin):
admin.site.register(BookmarkletImport, BookmarkletImportAdmin)
class TelegramBotAdmin(admin.ModelAdmin):
list_display = ('id', 'name', 'created_by',)

View File

@ -476,7 +476,7 @@ class BookmarkletImportSerializer(serializers.ModelSerializer):
class Meta:
model = BookmarkletImport
fields = ('id', 'url', 'html', 'created_by', 'created_at')
read_only_fields = ('created_by',)
read_only_fields = ('created_by', 'space')
# Export/Import Serializers

View File

@ -18,28 +18,30 @@
}
function initBookmarklet() {
(window.bookmarkletTandoor = function() {
var recipe = document.documentElement.innerHTML
var form = document.createElement("form");
var windowName = "ImportRecipe"
form.setAttribute("method", "post");
form.setAttribute("action", localStorage.getItem('importURL'));
form.setAttribute("target",'importRecipe');
var params = { 'recipe' : recipe,'url': window.location};
let recipe = document.documentElement.innerHTML
let windowName = "ImportRecipe"
let url = localStorage.getItem('importURL')
let redirect = localStorage.getItem('redirectURL')
let token = localStorage.getItem('token')
let params = { 'html' : recipe,'url': window.location.href};
console.log(window.location.href)
for (var i in params) {
if (params.hasOwnProperty(i)) {
var input = document.createElement('input');
input.type = 'hidden';
input.name = i;
input.value = params[i];
form.appendChild(input);
const xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Authorization', 'Token ' + token);
// listen for `onload` event
xhr.onload = () => {
// process response
if (xhr.readyState == 4 && xhr.status == 201) {
// parse JSON data
console.log(JSON.parse(xhr.response));
} else {
console.error('Error!');
}
}
document.body.appendChild(form);
window.open('', windowName);
form.target = windowName;
form.submit();
document.body.removeChild(form);
};
xhr.send(JSON.stringify(params));
}
)();
}

View File

@ -26,7 +26,7 @@
<h2> {% trans 'Import' %}</h2>
<a class="btn btn-outline-info btn-sm"
style="height:50%"
href="{% bookmarklet request.get_host request.is_secure %}"
href="{% bookmarklet request %}"
title="{% trans 'Drag me to your bookmarks to import recipes from anywhere' %}">
<img src="{% static 'assets/favicon-16x16.png' %}">{% trans 'Bookmark Me!' %} </a>
</div>

View File

@ -10,6 +10,7 @@ from django.db.models import Avg
from django.templatetags.static import static
from django.urls import NoReverseMatch, reverse
from recipes import settings
from rest_framework.authtoken.models import Token
from gettext import gettext as _
register = template.Library()
@ -111,20 +112,26 @@ def is_debug():
@register.simple_tag
def bookmarklet(host, secure):
if secure:
def bookmarklet(request):
if request.is_secure():
prefix = "https://"
else:
prefix = "http://"
server = prefix + request.get_host()
# TODO is it safe to store the token in clear text in a bookmark?
if (api_token := Token.objects.filter(user=request.user).first()) is None:
api_token = Token.objects.create(user=request.user)
bookmark = "javascript: \
(function(){ \
if(window.bookmarkletTandoor!==undefined){ \
bookmarkletTandoor(); \
} else { \
localStorage.setItem('importURL', '" + prefix + host + reverse('api_bookmarklet') + "'); \
localStorage.setItem('importURL', '" + server + reverse('api:bookmarkletimport-list') + "'); \
localStorage.setItem('redirectURL', '" + server + reverse('data_import_url') + "'); \
localStorage.setItem('token', '" + api_token.__str__() + "'); \
document.body.appendChild(document.createElement(\'script\')).src=\'" \
+ prefix + host + static('js/bookmarklet.js') + "? \
+ server + static('js/bookmarklet.js') + "? \
r=\'+Math.floor(Math.random()*999999999);}})();"
return re.sub(r"[\n\t]*", "", bookmark)
return re.sub(r"[\n\t\s]*", "", bookmark)

View File

@ -14,6 +14,7 @@ import os
import random
import string
from corsheaders.defaults import default_headers
from django.contrib import messages
from django.utils.translation import gettext_lazy as _
from dotenv import load_dotenv
@ -76,6 +77,7 @@ INSTALLED_APPS = [
'django.contrib.staticfiles',
'django.contrib.postgres',
'django_tables2',
'corsheaders',
'django_filters',
'crispy_forms',
'emoji_picker',
@ -97,6 +99,7 @@ SOCIALACCOUNT_PROVIDERS = ast.literal_eval(
os.getenv('SOCIALACCOUNT_PROVIDERS') if os.getenv('SOCIALACCOUNT_PROVIDERS') else '{}')
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
@ -249,5 +252,17 @@ STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
TEST_RUNNER = "cookbook.helper.CustomTestRunner.CustomTestRunner"
# future versions of django will make undeclared default django.db.models.BigAutoField which will force migrations on all models
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
# settings for cross site origin (CORS)
# all origins allowed to support bookmarklet
# all of this may or may not work with nginx or other web servers
# TODO make this user configureable - enable or disable bookmarklets
# TODO since token auth is enabled - this all should be https by default
CORS_ORIGIN_ALLOW_ALL = True
# django rest_framework requires authentication header
#CORS_ALLOW_HEADERS = list(default_headers) + ['authentication',]
# enable CORS only for bookmarklet api and only for posts, get and options
CORS_URLS_REGEX = r'^/api/bookmarklet-import.*$'
CORS_ALLOW_METHODS = ['GET', 'OPTIONS', 'POST']

View File

@ -33,5 +33,6 @@ django-js-reverse==0.9.1
django-allauth==0.44.0
recipe-scrapers==12.2.1
django-scopes==1.2.0
pytest==6.2.3
pytest-django==4.2.0
pytest==6.2.2
pytest-django==4.1.0
django-cors-headers==3.7.0