From e91a86a714686a22149b55c9d5f0210cec8fef52 Mon Sep 17 00:00:00 2001 From: HombreLaser Date: Thu, 8 Feb 2024 18:21:12 -0600 Subject: Add CORS --- config/__init__.py | 17 +++++++++++++++ main.py | 1 + requests.http | 2 +- requirements.txt | 2 ++ src/controllers/comments_controller.py | 19 ++++++++++------- src/controllers/replies_controller.py | 2 +- src/queries/comments_query.py | 11 ++++------ src/services/create_comment_service.py | 12 +++++------ static/js/client.js | 5 +++++ static/js/comments/comment_form.js | 31 ---------------------------- static/js/controllers/comments_controller.js | 31 ++++++++++++++++++++++++++++ static/js/main.js | 6 ------ templates/comments/form.jinja | 4 ---- 13 files changed, 79 insertions(+), 64 deletions(-) create mode 100644 static/js/client.js delete mode 100644 static/js/comments/comment_form.js create mode 100644 static/js/controllers/comments_controller.js delete mode 100644 static/js/main.js diff --git a/config/__init__.py b/config/__init__.py index 24ff968..6a623cf 100644 --- a/config/__init__.py +++ b/config/__init__.py @@ -1,6 +1,8 @@ import tomllib import re +from flask_cors import CORS import sqlalchemy.exc as sqlalchemy_exceptions +from sqlalchemy import select from src.database import db, init_db from src.database.models import Blog @@ -14,6 +16,7 @@ def initialize(app): # Check the config file for any blog domains. initialize_blogs(app) initialize_blueprints(app) + initialize_cors_policies(app) def database_connection_string(app): @@ -44,6 +47,20 @@ def initialize_blogs(app): break +def configured_blogs(app): + statement = select(Blog.domain).where(Blog.domain.in_(user_config['Blogs']['domains'])) + with app.app_context(): + return [r for r, in db.session.execute(statement)] + + +def initialize_cors_policies(app): + allowed_origins = configured_blogs(app) + cors_settings = {'resources': {r"/api/*": {'origins': allowed_origins}, + r"/static/*": {'origins': allowed_origins}} + } + CORS(app, **cors_settings) + + def initialize_blueprints(app): import src.controllers as app_controllers diff --git a/main.py b/main.py index 0016370..6912a5a 100644 --- a/main.py +++ b/main.py @@ -2,6 +2,7 @@ from flask import Flask from src.database import db import config + app = Flask(__name__) # Initialize database, blog domains... diff --git a/requests.http b/requests.http index 6f76bbb..85d50a1 100644 --- a/requests.http +++ b/requests.http @@ -1,4 +1,4 @@ -POST http://localhost:5000/what/a/good/post/comments +POST http://localhost:5000/api/comments?path=/what/a/good/post Content-Type: application/json { "email": "awesome@example.org", diff --git a/requirements.txt b/requirements.txt index a963528..9b8e0d4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,7 @@ Flask Flask-Migrate Flask-SQLAlchemy +Flask-WTF +flask-cors PyMySQL scrypt diff --git a/src/controllers/comments_controller.py b/src/controllers/comments_controller.py index 9d6f02e..706c213 100644 --- a/src/controllers/comments_controller.py +++ b/src/controllers/comments_controller.py @@ -8,25 +8,28 @@ comments_blueprint = Blueprint('comments_controller', query = CommentsQuery() -@comments_blueprint.post('//comments/') -def create(post): - service = CreateCommentService(request.get_json(), post) +@comments_blueprint.post('/api/comments') +def create(): + service = CreateCommentService(request.args | request.get_json()) status_code = service.call() if status_code == 404: abort(404) return render_template('comments/index.jinja', - page=query.comments_of_post(post)) + page=query.comments_of_post( + request.args.get('path') + )) -@comments_blueprint.get('//comments/new') -def new(post): +@comments_blueprint.get('/api/comments/new') +def new(): return render_template('comments/form.jinja') -@comments_blueprint.get('//comments/') -def index(post): +@comments_blueprint.get('/api/comments') +def index(): + post = request.args.get('path') page = query.comments_of_post(post) if page.total == 0: diff --git a/src/controllers/replies_controller.py b/src/controllers/replies_controller.py index 9228b5c..d7be3d0 100644 --- a/src/controllers/replies_controller.py +++ b/src/controllers/replies_controller.py @@ -6,7 +6,7 @@ replies_blueprint = Blueprint('replies_controller', '__replies_controller__') -@replies_blueprint.post('/comments//replies') +@replies_blueprint.post('/api/comments//replies') def create(comment_id): breakpoint() service = CreateReplyService(request.get_json(), comment_id) diff --git a/src/queries/comments_query.py b/src/queries/comments_query.py index 834bd6a..4bdf31f 100644 --- a/src/queries/comments_query.py +++ b/src/queries/comments_query.py @@ -7,13 +7,10 @@ class CommentsQuery(BaseQuery): def __init__(self): super().__init__(Comment) - def all_comments(self, page=1, per_page=10, max_per_page=15): - return db.paginate(db.select(Comment), page=page, per_page=per_page, - max_per_page=max_per_page) + def all_comments(self): + return db.paginate(db.select(Comment)) - def comments_of_post(self, post, page=1, per_page=10, max_per_page=15): + def comments_of_post(self, post): return db.paginate( - db.select(Comment).where(Comment.post == post), - page=page, per_page=per_page, - max_per_page=max_per_page + db.select(Comment).where(Comment.post == self._post), ) diff --git a/src/services/create_comment_service.py b/src/services/create_comment_service.py index 97cf726..ef8b105 100644 --- a/src/services/create_comment_service.py +++ b/src/services/create_comment_service.py @@ -5,12 +5,12 @@ from src.services.comment_creation_callbacks import CommentCreationCallbacks class CreateCommentService: - def __init__(self, comment_data, post): - self._post = post - self._domain = comment_data.get('domain') - self._content = comment_data.get('content') - self._email = comment_data.get('email') - self._author = comment_data.get('author') + def __init__(self, params): + self._post = params.get('path') + self._domain = params.get('domain') + self._content = params.get('content') + self._email = params.get('email') + self._author = params.get('author') self._blog_id = self._get_blog_id() def _get_blog_id(self): diff --git a/static/js/client.js b/static/js/client.js new file mode 100644 index 0000000..d782871 --- /dev/null +++ b/static/js/client.js @@ -0,0 +1,5 @@ +import { CommentsController} from "./comments/comments_controller.js"; + +const post = window.location.pathname; +const domain = window.location.hostname; +new CommentForm(domain, post); diff --git a/static/js/comments/comment_form.js b/static/js/comments/comment_form.js deleted file mode 100644 index 6edde9f..0000000 --- a/static/js/comments/comment_form.js +++ /dev/null @@ -1,31 +0,0 @@ -class CommentForm { - constructor(domain, post) { - this.domain = domain; - this.post = post; - this.parser = new DOMParser(); - this.form_element = document.getElementById("comment-form"); - this.form_element.addEventListener("submit", this.submit.bind(this)); - } - - async submit(event) { - const form = new FormData(event.target); - form.append("domain", window.location.hostname); - - try { - const response = await fetch(`https://${this.domain}/${this.post}/comments`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: form - }); - const response_page = this.htmlFromResponse(response.body); - } catch(error) {} - } - - htmlFromResponse(body) { - return this.parser.parseFromString(body, "text/html"); - } - } - diff --git a/static/js/controllers/comments_controller.js b/static/js/controllers/comments_controller.js new file mode 100644 index 0000000..611b2ee --- /dev/null +++ b/static/js/controllers/comments_controller.js @@ -0,0 +1,31 @@ +export class CommentsController { + constructor(domain, post) { + this.domain = domain; + this.post = post; + this.parser = new DOMParser(); + this.form_element = document.getElementById("comment-form"); + this.form_element.addEventListener("submit", this.submit.bind(this)); + } + + async submit(event) { + const form = new FormData(event.target); + form.append("domain", window.location.hostname); + + try { + const response = await fetch(`https://${this.domain}/${this.post}/comments`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: form + }); + const response_page = this.htmlFromResponse(response.body); + } catch(error) {} + } + + htmlFromResponse(body) { + return this.parser.parseFromString(body, "text/html"); + } + } + diff --git a/static/js/main.js b/static/js/main.js deleted file mode 100644 index cfb02dc..0000000 --- a/static/js/main.js +++ /dev/null @@ -1,6 +0,0 @@ -import CommentForm from "./comments/comment_form"; - - -const post = window.location.pathname; -const domain = window.location.hostname; -new CommentForm(domain, post); diff --git a/templates/comments/form.jinja b/templates/comments/form.jinja index 4934149..8666c2d 100644 --- a/templates/comments/form.jinja +++ b/templates/comments/form.jinja @@ -15,7 +15,3 @@ - - -- cgit v1.2.3