diff --git a/changedetectionio/api/api_v1.py b/changedetectionio/api/api_v1.py
index fc09bb1b..72598188 100644
--- a/changedetectionio/api/api_v1.py
+++ b/changedetectionio/api/api_v1.py
@@ -285,8 +285,6 @@ class CreateWatch(Resource):
list = {}
tag_limit = request.args.get('tag', '').lower()
-
-
for uuid, watch in self.datastore.data['watching'].items():
# Watch tags by name (replace the other calls?)
tags = self.datastore.get_all_tags_for_watch(uuid=uuid)
diff --git a/changedetectionio/api/auth.py b/changedetectionio/api/auth.py
index 806a8ccd..64e8dbb1 100644
--- a/changedetectionio/api/auth.py
+++ b/changedetectionio/api/auth.py
@@ -11,22 +11,14 @@ def check_token(f):
datastore = args[0].datastore
config_api_token_enabled = datastore.data['settings']['application'].get('api_access_token_enabled')
- if not config_api_token_enabled:
- return
-
- try:
- api_key_header = request.headers['x-api-key']
- except KeyError:
- return make_response(
- jsonify("No authorization x-api-key header."), 403
- )
-
config_api_token = datastore.data['settings']['application'].get('api_access_token')
- if api_key_header != config_api_token:
- return make_response(
- jsonify("Invalid access - API key invalid."), 403
- )
+ # config_api_token_enabled - a UI option in settings if access should obey the key or not
+ if config_api_token_enabled:
+ if request.headers.get('x-api-key') != config_api_token:
+ return make_response(
+ jsonify("Invalid access - API key invalid."), 403
+ )
return f(*args, **kwargs)
diff --git a/changedetectionio/flask_app.py b/changedetectionio/flask_app.py
index 232ad944..44707bd4 100644
--- a/changedetectionio/flask_app.py
+++ b/changedetectionio/flask_app.py
@@ -4,7 +4,6 @@
import flask_login
import locale
import os
-import pytz
import queue
import threading
import time
@@ -244,6 +243,9 @@ def changedetection_app(config=None, datastore_o=None):
# RSS access with token is allowed
elif request.endpoint and 'rss.feed' in request.endpoint:
return None
+ # API routes - use their own auth mechanism (@auth.check_token)
+ elif request.path.startswith('/api/'):
+ return None
else:
return login_manager.unauthorized()
diff --git a/changedetectionio/tests/test_api.py b/changedetectionio/tests/test_api.py
index 097133fe..d57d5bac 100644
--- a/changedetectionio/tests/test_api.py
+++ b/changedetectionio/tests/test_api.py
@@ -2,7 +2,7 @@
import time
from flask import url_for
-from .util import live_server_setup, extract_api_key_from_UI, wait_for_all_checks
+from .util import live_server_setup, wait_for_all_checks
import json
import uuid
@@ -57,16 +57,15 @@ def test_setup(client, live_server, measure_memory_usage):
def test_api_simple(client, live_server, measure_memory_usage):
-# live_server_setup(live_server)
+ #live_server_setup(live_server)
- api_key = extract_api_key_from_UI(client)
+ api_key = live_server.app.config['DATASTORE'].data['settings']['application'].get('api_access_token')
# Create a watch
set_original_response()
# Validate bad URL
- test_url = url_for('test_endpoint', _external=True,
- headers={'x-api-key': api_key}, )
+ test_url = url_for('test_endpoint', _external=True )
res = client.post(
url_for("createwatch"),
data=json.dumps({"url": "h://xxxxxxxxxom"}),
@@ -293,12 +292,11 @@ def test_access_denied(client, live_server, measure_memory_usage):
def test_api_watch_PUT_update(client, live_server, measure_memory_usage):
#live_server_setup(live_server)
- api_key = extract_api_key_from_UI(client)
+ api_key = live_server.app.config['DATASTORE'].data['settings']['application'].get('api_access_token')
# Create a watch
set_original_response()
- test_url = url_for('test_endpoint', _external=True,
- headers={'x-api-key': api_key}, )
+ test_url = url_for('test_endpoint', _external=True)
# Create new
res = client.post(
@@ -374,7 +372,7 @@ def test_api_watch_PUT_update(client, live_server, measure_memory_usage):
def test_api_import(client, live_server, measure_memory_usage):
#live_server_setup(live_server)
- api_key = extract_api_key_from_UI(client)
+ api_key = live_server.app.config['DATASTORE'].data['settings']['application'].get('api_access_token')
res = client.post(
url_for("import") + "?tag=import-test",
@@ -392,4 +390,48 @@ def test_api_import(client, live_server, measure_memory_usage):
# Should see the new tag in the tag/groups list
res = client.get(url_for('tags.tags_overview_page'))
assert b'import-test' in res.data
-
\ No newline at end of file
+
+def test_api_conflict_UI_password(client, live_server, measure_memory_usage):
+
+ #live_server_setup(live_server)
+ api_key = live_server.app.config['DATASTORE'].data['settings']['application'].get('api_access_token')
+
+ # Enable password check and diff page access bypass
+ res = client.post(
+ url_for("settings.settings_page"),
+ data={"application-password": "foobar", # password is now set! API should still work!
+ "application-api_access_token_enabled": "y",
+ "requests-time_between_check-minutes": 180,
+ 'application-fetch_backend': "html_requests"},
+ follow_redirects=True
+ )
+
+ assert b"Password protection enabled." in res.data
+
+ # Create a watch
+ set_original_response()
+ test_url = url_for('test_endpoint', _external=True)
+
+ # Create new
+ res = client.post(
+ url_for("createwatch"),
+ data=json.dumps({"url": test_url, "title": "My test URL" }),
+ headers={'content-type': 'application/json', 'x-api-key': api_key},
+ follow_redirects=True
+ )
+
+ assert res.status_code == 201
+
+
+ wait_for_all_checks(client)
+ url = url_for("createwatch")
+ # Get a listing, it will be the first one
+ res = client.get(
+ url,
+ headers={'x-api-key': api_key}
+ )
+ assert res.status_code == 200
+
+ assert len(res.json)
+
+
diff --git a/changedetectionio/tests/test_automatic_follow_ldjson_price.py b/changedetectionio/tests/test_automatic_follow_ldjson_price.py
index 2e085d3f..1996e72c 100644
--- a/changedetectionio/tests/test_automatic_follow_ldjson_price.py
+++ b/changedetectionio/tests/test_automatic_follow_ldjson_price.py
@@ -2,7 +2,7 @@
import time
from flask import url_for
-from .util import live_server_setup, extract_UUID_from_client, extract_api_key_from_UI, wait_for_all_checks
+from .util import live_server_setup, extract_UUID_from_client, wait_for_all_checks
def set_response_with_ldjson():
@@ -110,7 +110,7 @@ def test_check_ldjson_price_autodetect(client, live_server, measure_memory_usage
assert b'tracking-ldjson-price-data' in res.data
# and last snapshop (via API) should be just the price
- api_key = extract_api_key_from_UI(client)
+ api_key = live_server.app.config['DATASTORE'].data['settings']['application'].get('api_access_token')
res = client.get(
url_for("watchsinglehistory", uuid=uuid, timestamp='latest'),
headers={'x-api-key': api_key},
diff --git a/changedetectionio/tests/util.py b/changedetectionio/tests/util.py
index 2ffe79d1..c4e6b316 100644
--- a/changedetectionio/tests/util.py
+++ b/changedetectionio/tests/util.py
@@ -95,20 +95,6 @@ def wait_for_notification_endpoint_output():
return False
-
-# kinda funky, but works for now
-def extract_api_key_from_UI(client):
- import re
- res = client.get(
- url_for("settings.settings_page"),
- )
- # {{api_key}}
-
- m = re.search('(.+?)', str(res.data))
- api_key = m.group(1)
- return api_key.strip()
-
-
# kinda funky, but works for now
def get_UUID_for_tag_name(client, name):
app_config = client.application.config.get('DATASTORE').data