Skip to content

Commit

Permalink
For UX reasons, strip whitespace from API keys when validating
Browse files Browse the repository at this point in the history
  • Loading branch information
calpaterson committed Aug 8, 2024
1 parent f14d8f1 commit 3146534
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 1 deletion.
10 changes: 10 additions & 0 deletions csvbase/svc.py
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,16 @@ def is_correct_password(


def is_valid_api_key(sesh: Session, username: str, hex_api_key: str) -> bool:
"""Return True if the provided api key is valid for that user, False otherwise."""

# Strip whitespace here to improve usability.
#
# API keys do not contain whitespace. People often copy their key straight
# from the website into an obscured password input field. If whitepace got
# added somewhere along the way (common when copying+pasting from websites)
# then they end up very confused.
hex_api_key = hex_api_key.strip()

try:
api_key = binascii.unhexlify(hex_api_key)
except binascii.Error:
Expand Down
31 changes: 30 additions & 1 deletion tests/test_web_session.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import pytest
"""Tests for authentication (the "web session")."""

from base64 import b64encode

import pytest

from csvbase import svc
from csvbase.value_objs import ContentType
Expand Down Expand Up @@ -88,3 +91,29 @@ def test_sign_out(client, test_user, whence):
expected_location = whence
assert expected_location == resp.headers["Location"]
assert resp.headers["Clear-Site-Data"] == "*"


def test_api_key__invalid(client, test_user, ten_rows):
"""Test for an incorrectly formatted api key (most often this is a user's own password)."""
encoded = b64encode(f"{test_user.username}:password".encode("utf-8")).decode(
"utf-8"
)
authorization = f"Basic {encoded}"
resp = client.get(
f"{test_user.username}/{ten_rows.table_name}",
headers={"Authorization": authorization},
)
assert resp.status_code == 400
assert resp.json == {"error": "invalid api key"}


def test_api_key__with_whitespace(client, test_user, ten_rows):
encoded = b64encode(
f"{test_user.username}: {test_user.hex_api_key()}".encode("utf-8")
).decode("utf-8")
authorization = f"Basic {encoded}"
resp = client.get(
f"{test_user.username}/{ten_rows.table_name}",
headers={"Authorization": authorization},
)
assert resp.status_code == 200

0 comments on commit 3146534

Please sign in to comment.