mirror of
https://github.com/dgtlmoon/changedetection.io.git
synced 2025-11-06 09:35:48 +00:00
Compare commits
2 Commits
0.50.4
...
regression
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bfa4482fb8 | ||
|
|
a00e69abed |
@@ -20,10 +20,7 @@ def login_optionally_required(func):
|
|||||||
has_password_enabled = datastore.data['settings']['application'].get('password') or os.getenv("SALTED_PASS", False)
|
has_password_enabled = datastore.data['settings']['application'].get('password') or os.getenv("SALTED_PASS", False)
|
||||||
|
|
||||||
# Permitted
|
# Permitted
|
||||||
if request.endpoint and 'static_content' in request.endpoint and request.view_args and request.view_args.get('group') == 'styles':
|
if request.endpoint and 'diff_history_page' in request.endpoint and datastore.data['settings']['application'].get('shared_diff_access'):
|
||||||
return func(*args, **kwargs)
|
|
||||||
# Permitted
|
|
||||||
elif request.endpoint and 'diff_history_page' in request.endpoint and datastore.data['settings']['application'].get('shared_diff_access'):
|
|
||||||
return func(*args, **kwargs)
|
return func(*args, **kwargs)
|
||||||
elif request.method in flask_login.config.EXEMPT_METHODS:
|
elif request.method in flask_login.config.EXEMPT_METHODS:
|
||||||
return func(*args, **kwargs)
|
return func(*args, **kwargs)
|
||||||
|
|||||||
@@ -233,7 +233,8 @@ def changedetection_app(config=None, datastore_o=None):
|
|||||||
|
|
||||||
if has_password_enabled and not flask_login.current_user.is_authenticated:
|
if has_password_enabled and not flask_login.current_user.is_authenticated:
|
||||||
# Permitted
|
# Permitted
|
||||||
if request.endpoint and request.endpoint == 'static_content' and request.view_args and request.view_args.get('group') in ['styles', 'js', 'images', 'favicons']:
|
if request.endpoint and request.endpoint == 'static_content' and request.view_args:
|
||||||
|
# Handled by static_content handler
|
||||||
return None
|
return None
|
||||||
# Permitted
|
# Permitted
|
||||||
elif request.endpoint and 'login' in request.endpoint:
|
elif request.endpoint and 'login' in request.endpoint:
|
||||||
@@ -351,11 +352,15 @@ def changedetection_app(config=None, datastore_o=None):
|
|||||||
@app.route("/static/<string:group>/<string:filename>", methods=['GET'])
|
@app.route("/static/<string:group>/<string:filename>", methods=['GET'])
|
||||||
def static_content(group, filename):
|
def static_content(group, filename):
|
||||||
from flask import make_response
|
from flask import make_response
|
||||||
|
import re
|
||||||
|
group = re.sub(r'[^\w.-]+', '', group.lower())
|
||||||
|
filename = re.sub(r'[^\w.-]+', '', filename.lower())
|
||||||
|
|
||||||
if group == 'screenshot':
|
if group == 'screenshot':
|
||||||
# Could be sensitive, follow password requirements
|
# Could be sensitive, follow password requirements
|
||||||
if datastore.data['settings']['application']['password'] and not flask_login.current_user.is_authenticated:
|
if datastore.data['settings']['application']['password'] and not flask_login.current_user.is_authenticated:
|
||||||
abort(403)
|
if not datastore.data['settings']['application'].get('shared_diff_access'):
|
||||||
|
abort(403)
|
||||||
|
|
||||||
screenshot_filename = "last-screenshot.png" if not request.args.get('error_screenshot') else "last-error-screenshot.png"
|
screenshot_filename = "last-screenshot.png" if not request.args.get('error_screenshot') else "last-error-screenshot.png"
|
||||||
|
|
||||||
@@ -404,7 +409,7 @@ def changedetection_app(config=None, datastore_o=None):
|
|||||||
|
|
||||||
# These files should be in our subdirectory
|
# These files should be in our subdirectory
|
||||||
try:
|
try:
|
||||||
return send_from_directory("static/{}".format(group), path=filename)
|
return send_from_directory(f"static/{group}", path=filename)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,11 @@ def test_check_access_control(app, client, live_server):
|
|||||||
res = c.get(url_for('static_content', group='styles', filename='404-testetest.css'))
|
res = c.get(url_for('static_content', group='styles', filename='404-testetest.css'))
|
||||||
assert res.status_code == 404
|
assert res.status_code == 404
|
||||||
|
|
||||||
|
# Access to screenshots should be limited by 'shared_diff_access'
|
||||||
|
path = url_for('static_content', group='screenshot', filename='random-uuid-that-will-404.png', _external=True)
|
||||||
|
res = c.get(path)
|
||||||
|
assert res.status_code == 404
|
||||||
|
|
||||||
# Check wrong password does not let us in
|
# Check wrong password does not let us in
|
||||||
res = c.post(
|
res = c.post(
|
||||||
url_for("login"),
|
url_for("login"),
|
||||||
@@ -163,7 +168,7 @@ def test_check_access_control(app, client, live_server):
|
|||||||
url_for("settings.settings_page"),
|
url_for("settings.settings_page"),
|
||||||
data={"application-password": "foobar",
|
data={"application-password": "foobar",
|
||||||
# Should be disabled
|
# Should be disabled
|
||||||
# "application-shared_diff_access": "True",
|
"application-shared_diff_access": "",
|
||||||
"requests-time_between_check-minutes": 180,
|
"requests-time_between_check-minutes": 180,
|
||||||
'application-fetch_backend': "html_requests"},
|
'application-fetch_backend': "html_requests"},
|
||||||
follow_redirects=True
|
follow_redirects=True
|
||||||
@@ -176,6 +181,10 @@ def test_check_access_control(app, client, live_server):
|
|||||||
# Should be logged out
|
# Should be logged out
|
||||||
assert b"Login" in res.data
|
assert b"Login" in res.data
|
||||||
|
|
||||||
|
# Access to screenshots should be limited by 'shared_diff_access'
|
||||||
|
res = c.get(url_for('static_content', group='screenshot', filename='random-uuid-that-will-403.png'))
|
||||||
|
assert res.status_code == 403
|
||||||
|
|
||||||
# The diff page should return something valid when logged out
|
# The diff page should return something valid when logged out
|
||||||
res = c.get(url_for("ui.ui_views.diff_history_page", uuid="first"))
|
res = c.get(url_for("ui.ui_views.diff_history_page", uuid="first"))
|
||||||
assert b'Random content' not in res.data
|
assert b'Random content' not in res.data
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import json
|
import json
|
||||||
import urllib
|
import time
|
||||||
|
|
||||||
from flask import url_for
|
from flask import url_for
|
||||||
from .util import live_server_setup, wait_for_all_checks
|
from .util import live_server_setup, wait_for_all_checks
|
||||||
@@ -113,6 +113,7 @@ def test_conditions_with_text_and_number(client, live_server):
|
|||||||
client.get(url_for("ui.form_watch_checknow"), follow_redirects=True)
|
client.get(url_for("ui.form_watch_checknow"), follow_redirects=True)
|
||||||
wait_for_all_checks(client)
|
wait_for_all_checks(client)
|
||||||
|
|
||||||
|
time.sleep(2)
|
||||||
# 75 is > 20 and < 100 and contains "5"
|
# 75 is > 20 and < 100 and contains "5"
|
||||||
res = client.get(url_for("watchlist.index"))
|
res = client.get(url_for("watchlist.index"))
|
||||||
assert b'unviewed' in res.data
|
assert b'unviewed' in res.data
|
||||||
|
|||||||
Reference in New Issue
Block a user