Skip to content

Commit

Permalink
Add a new api endpoint for checking api keys
Browse files Browse the repository at this point in the history
To help the extension tell users when they have it wrong
  • Loading branch information
calpaterson committed Oct 10, 2020
1 parent 1bcfcf9 commit d246740
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 4 deletions.
27 changes: 23 additions & 4 deletions src/server/quarchive/web/blueprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,17 +167,29 @@ def wrapper(*args, **kwargs):

cache = get_cache()
if is_correct_api_key(db.session, cache, username, bytes.fromhex(api_key_str)):
flask.g.user = user_from_username_if_exists(db.session, cache, username)
# We know at this point that the user does in fact exist, so cast
# away the Optional
user = cast(User, user_from_username_if_exists(db.session, cache, username))
flask.g.user = user
return handler()
else:
flask.current_app.logger.info("bad api credentials")
return flask.jsonify({"error": "bad api credentials"}), 400
# Something was wrong, let's figure out what
user_if_exists = user_from_username_if_exists(db.session, cache, username)
if user_if_exists is None:
flask.current_app.logger.warning("user does not exist: %s", username)
# user doesn't exist
return flask.jsonify({"error": "user does not exist"}), 400
else:
flask.current_app.logger.warning("wrong api key for %s", username)
# api key must have been wrong
return flask.jsonify({"error": "bad api key"}), 400

return cast(V, wrapper)


@blueprint.route("/favicon.ico")
def favicon() -> flask.Response:
# Should set cache headers
return flask.current_app.send_static_file("icons/favicon.ico")


Expand Down Expand Up @@ -686,7 +698,14 @@ def ok() -> flask.Response:
return flask.json.jsonify({"ok": True})


@blueprint.route("/sync", methods=["POST"])
@blueprint.route("/api/sync/check-api-key", methods=["POST"])
@api_key_required
def sync_check_api_key() -> Tuple[flask.Response, int]:
return flask.jsonify({}), 200


@blueprint.route("/api/sync", methods=["POST"])
@blueprint.route("/sync", methods=["POST"]) # FIXME: Deprecated
@api_key_required
def sync() -> flask.Response:
extension_version = flask.request.headers.get(
Expand Down
39 changes: 39 additions & 0 deletions src/server/tests/test_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,45 @@
from .conftest import make_bookmark


def test_check_api_key_user_does_not_exist(client, session):
response = client.post(
"/api/sync/check-api-key",
headers={"Quarchive-Username": "nobody", "Quarchive-API-Key": "deadbeef",},
)
assert response.status_code == 400
assert response.json == {"error": "user does not exist"}


def test_check_api_key_no_credentials(client, session):
response = client.post("/api/sync/check-api-key")
assert response.status_code == 400
assert response.json == {"error": "no api credentials"}


def test_check_api_key_wrong_api_key(client, session, test_user):
response = client.post(
"/api/sync/check-api-key",
headers={
"Quarchive-Username": test_user.username,
"Quarchive-API-Key": "deadbeef",
},
)
assert response.status_code == 400
assert response.json == {"error": "bad api key"} # FIXME: error could be better


def test_check_api_key_right_creds(client, session, test_user):
response = client.post(
"/api/sync/check-api-key",
headers={
"Quarchive-Username": test_user.username,
"Quarchive-API-Key": test_user.api_key.hex(),
},
)
assert response.status_code == 200
assert response.json == {}


def test_no_credentials(client, session):
response = client.post("/sync", json={"bookmarks": []},)
assert response.status_code == 400
Expand Down

0 comments on commit d246740

Please sign in to comment.