import sys
from html.parser import HTMLParser
import requests
from httpretty import HTTPretty
from openid import oidutil
from ...backends.utils import load_backends
from ...utils import module_member, parse_qs
from ..models import TestAssociation, TestNonce, TestStorage, TestUserSocialAuth, User
from ..strategy import TestStrategy
from .base import BaseBackendTest
sys.path.insert(0, "..")
# Patch to remove the too-verbose output until a new version is released
oidutil.log = lambda *args, **kwargs: None
class FormHTMLParser(HTMLParser):
form = {}
inputs = {}
def handle_starttag(self, tag, attrs):
attrs = dict(attrs)
if tag == "form":
self.form.update(attrs)
elif tag == "input" and "name" in attrs:
self.inputs[attrs["name"]] = attrs["value"]
class OpenIdTest(BaseBackendTest):
backend_path = None
backend = None
access_token_body = None
user_data_body = None
user_data_url = ""
expected_username = ""
settings = None
partial_login_settings = None
raw_complete_url = "/complete/{0}/"
def setUp(self):
HTTPretty.enable(allow_net_connect=False)
Backend = module_member(self.backend_path)
self.strategy = TestStrategy(TestStorage)
self.complete_url = self.raw_complete_url.format(Backend.name)
self.backend = Backend(self.strategy, redirect_uri=self.complete_url)
self.strategy.set_settings(
{
"SOCIAL_AUTH_AUTHENTICATION_BACKENDS": (
self.backend_path,
"social_core.tests.backends.test_broken.BrokenBackendAuth",
)
}
)
# Force backends loading to trash PSA cache
load_backends(
self.strategy.get_setting("SOCIAL_AUTH_AUTHENTICATION_BACKENDS"),
force_load=True,
)
def tearDown(self):
self.strategy = None
User.reset_cache()
TestUserSocialAuth.reset_cache()
TestNonce.reset_cache()
TestAssociation.reset_cache()
HTTPretty.disable()
HTTPretty.reset()
def get_form_data(self, html):
parser = FormHTMLParser()
parser.feed(html)
return parser.form, parser.inputs
def openid_url(self):
return self.backend.openid_url()
def post_start(self):
pass
def do_start(self):
HTTPretty.register_uri(
HTTPretty.GET,
self.openid_url(),
status=200,
body=self.discovery_body,
content_type="application/xrds+xml",
)
start = self.backend.start()
self.post_start()
form, inputs = self.get_form_data(start)
HTTPretty.register_uri(
HTTPretty.POST, form.get("action"), status=200, body=self.server_response
)
response = requests.post(form.get("action"), data=inputs)
self.strategy.set_request_data(parse_qs(response.content), self.backend)
HTTPretty.register_uri(
HTTPretty.POST, form.get("action"), status=200, body="is_valid:true\n"
)
return self.backend.complete()