Simple HTTP auth (#372)

HTTP Basic Auth form validation
pull/374/head
dgtlmoon 3 years ago committed by GitHub
parent e5fe095f16
commit a896493797
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -628,6 +628,7 @@ def changedetection_app(config=None, datastore_o=None):
urls = request.values.get('urls').split("\n") urls = request.values.get('urls').split("\n")
for url in urls: for url in urls:
url = url.strip() url = url.strip()
# Flask wtform validators wont work with basic auth, use validators package
if len(url) and validators.url(url): if len(url) and validators.url(url):
new_uuid = datastore.add_watch(url=url.strip(), tag="") new_uuid = datastore.add_watch(url=url.strip(), tag="")
# Straight into the queue. # Straight into the queue.

@ -176,7 +176,24 @@ class ValidateTokensList(object):
if not p.strip('{}') in notification.valid_tokens: if not p.strip('{}') in notification.valid_tokens:
message = field.gettext('Token \'%s\' is not a valid token.') message = field.gettext('Token \'%s\' is not a valid token.')
raise ValidationError(message % (p)) raise ValidationError(message % (p))
class validateURL(object):
"""
Flask wtform validators wont work with basic auth
"""
def __init__(self, message=None):
self.message = message
def __call__(self, form, field):
import validators
try:
validators.url(field.data.strip())
except validators.ValidationFailure:
message = field.gettext('\'%s\' is not a valid URL.' % (field.data.strip()))
raise ValidationError(message)
class ValidateListRegex(object): class ValidateListRegex(object):
""" """
Validates that anything that looks like a regex passes as a regex Validates that anything that looks like a regex passes as a regex
@ -244,7 +261,7 @@ class ValidateCSSJSONXPATHInput(object):
class quickWatchForm(Form): class quickWatchForm(Form):
# https://wtforms.readthedocs.io/en/2.3.x/fields/#module-wtforms.fields.html5 # https://wtforms.readthedocs.io/en/2.3.x/fields/#module-wtforms.fields.html5
# `require_tld` = False is needed even for the test harness "http://localhost:5005.." to run # `require_tld` = False is needed even for the test harness "http://localhost:5005.." to run
url = html5.URLField('URL', [validators.URL(require_tld=False)]) url = html5.URLField('URL', validators=[validateURL()])
tag = StringField('Group tag', [validators.Optional(), validators.Length(max=35)]) tag = StringField('Group tag', [validators.Optional(), validators.Length(max=35)])
class commonSettingsForm(Form): class commonSettingsForm(Form):
@ -259,7 +276,7 @@ class commonSettingsForm(Form):
class watchForm(commonSettingsForm): class watchForm(commonSettingsForm):
url = html5.URLField('URL', [validators.URL(require_tld=False)]) url = html5.URLField('URL', validators=[validateURL()])
tag = StringField('Group tag', [validators.Optional(), validators.Length(max=35)]) tag = StringField('Group tag', [validators.Optional(), validators.Length(max=35)])
minutes_between_check = html5.IntegerField('Maximum time in minutes until recheck', minutes_between_check = html5.IntegerField('Maximum time in minutes until recheck',

@ -0,0 +1,39 @@
#!/usr/bin/python3
import time
from flask import url_for
from . util import live_server_setup
def test_basic_auth(client, live_server):
live_server_setup(live_server)
# Give the endpoint time to spin up
time.sleep(1)
# Add our URL to the import page
test_url = url_for('test_basicauth_method', _external=True).replace("//","//myuser:mypass@")
res = client.post(
url_for("import_page"),
data={"urls": test_url},
follow_redirects=True
)
assert b"1 Imported" in res.data
# Check form validation
res = client.post(
url_for("edit_page", uuid="first"),
data={"css_filter": "", "url": test_url, "tag": "", "headers": "", 'fetch_backend': "html_requests"},
follow_redirects=True
)
assert b"Updated watch." in res.data
# Trigger a check
client.get(url_for("api_watch_checknow"), follow_redirects=True)
time.sleep(1)
res = client.get(
url_for("preview_page", uuid="first"),
follow_redirects=True
)
assert b'myuser mypass basic' in res.data

@ -103,4 +103,14 @@ def live_server_setup(live_server):
print("\n>> Test notification endpoint was hit.\n") print("\n>> Test notification endpoint was hit.\n")
return "Text was set" return "Text was set"
# Just return the verb in the request
@live_server.app.route('/test-basicauth', methods=['GET'])
def test_basicauth_method():
from flask import request
auth = request.authorization
ret = " ".join([auth.username, auth.password, auth.type])
return ret
live_server.start() live_server.start()

Loading…
Cancel
Save