mirror of
https://github.com/hanzoai/sentinel.git
synced 2026-09-29 22:34:33 +00:00
180 lines
6.7 KiB
Python
180 lines
6.7 KiB
Python
from collections import namedtuple
|
|
from functools import cached_property
|
|
from urllib.parse import parse_qs, parse_qsl, urlparse
|
|
|
|
import responses
|
|
from django.test import Client, RequestFactory
|
|
from requests.exceptions import SSLError
|
|
|
|
import sentry.identity
|
|
from sentry.identity.oauth2 import OAuth2CallbackView, OAuth2LoginView
|
|
from sentry.identity.pipeline import IdentityProviderPipeline
|
|
from sentry.identity.providers.dummy import DummyProvider
|
|
from sentry.testutils.cases import TestCase
|
|
from sentry.testutils.silo import control_silo_test
|
|
|
|
MockResponse = namedtuple("MockResponse", ["headers", "content"])
|
|
|
|
|
|
@control_silo_test
|
|
class OAuth2CallbackViewTest(TestCase):
|
|
def setUp(self):
|
|
sentry.identity.register(DummyProvider)
|
|
super().setUp()
|
|
self.request = RequestFactory().get("/")
|
|
self.request.subdomain = None
|
|
|
|
def tearDown(self):
|
|
super().tearDown()
|
|
sentry.identity.unregister(DummyProvider)
|
|
|
|
@cached_property
|
|
def view(self):
|
|
return OAuth2CallbackView(
|
|
access_token_url="https://example.org/oauth/token",
|
|
client_id=123456,
|
|
client_secret="secret-value",
|
|
)
|
|
|
|
@responses.activate
|
|
def test_exchange_token_success(self):
|
|
responses.add(
|
|
responses.POST, "https://example.org/oauth/token", json={"token": "a-fake-token"}
|
|
)
|
|
|
|
pipeline = IdentityProviderPipeline(request=self.request, provider_key="dummy")
|
|
code = "auth-code"
|
|
result = self.view.exchange_token(self.request, pipeline, code)
|
|
assert "token" in result
|
|
assert "a-fake-token" == result["token"]
|
|
|
|
assert len(responses.calls) == 1
|
|
assert responses.calls[0].request.url == "https://example.org/oauth/token"
|
|
data = dict(parse_qsl(responses.calls[0].request.body))
|
|
assert data == {
|
|
"client_id": "123456",
|
|
"client_secret": "secret-value",
|
|
"code": "auth-code",
|
|
"grant_type": "authorization_code",
|
|
"redirect_uri": "http://testserver/extensions/default/setup/",
|
|
}
|
|
|
|
@responses.activate
|
|
def test_exchange_token_success_customer_domains(self):
|
|
responses.add(
|
|
responses.POST, "https://example.org/oauth/token", json={"token": "a-fake-token"}
|
|
)
|
|
self.request.subdomain = "albertos-apples"
|
|
pipeline = IdentityProviderPipeline(request=self.request, provider_key="dummy")
|
|
code = "auth-code"
|
|
result = self.view.exchange_token(self.request, pipeline, code)
|
|
assert "token" in result
|
|
assert "a-fake-token" == result["token"]
|
|
|
|
assert len(responses.calls) == 1
|
|
assert responses.calls[0].request.url == "https://example.org/oauth/token"
|
|
data = dict(parse_qsl(responses.calls[0].request.body))
|
|
assert data == {
|
|
"client_id": "123456",
|
|
"client_secret": "secret-value",
|
|
"code": "auth-code",
|
|
"grant_type": "authorization_code",
|
|
"redirect_uri": "http://testserver/extensions/default/setup/",
|
|
}
|
|
|
|
@responses.activate
|
|
def test_exchange_token_ssl_error(self):
|
|
def ssl_error(request):
|
|
raise SSLError("Could not build connection")
|
|
|
|
responses.add_callback(
|
|
responses.POST, "https://example.org/oauth/token", callback=ssl_error
|
|
)
|
|
pipeline = IdentityProviderPipeline(request=self.request, provider_key="dummy")
|
|
code = "auth-code"
|
|
result = self.view.exchange_token(self.request, pipeline, code)
|
|
assert "token" not in result
|
|
assert "error" in result
|
|
assert "error_description" in result
|
|
assert "SSL" in result["error_description"]
|
|
|
|
@responses.activate
|
|
def test_connection_error(self):
|
|
def connection_error(request):
|
|
raise ConnectionError("Name or service not known")
|
|
|
|
responses.add_callback(
|
|
responses.POST, "https://example.org/oauth/token", callback=connection_error
|
|
)
|
|
pipeline = IdentityProviderPipeline(request=self.request, provider_key="dummy")
|
|
code = "auth-code"
|
|
result = self.view.exchange_token(self.request, pipeline, code)
|
|
assert "token" not in result
|
|
assert "error" in result
|
|
assert "connect" in result["error"]
|
|
assert "error_description" in result
|
|
|
|
@responses.activate
|
|
def test_exchange_token_no_json(self):
|
|
responses.add(responses.POST, "https://example.org/oauth/token", body="")
|
|
pipeline = IdentityProviderPipeline(request=self.request, provider_key="dummy")
|
|
code = "auth-code"
|
|
result = self.view.exchange_token(self.request, pipeline, code)
|
|
assert "token" not in result
|
|
assert "error" in result
|
|
assert "error_description" in result
|
|
assert "JSON" in result["error_description"]
|
|
|
|
|
|
@control_silo_test
|
|
class OAuth2LoginViewTest(TestCase):
|
|
def setUp(self):
|
|
sentry.identity.register(DummyProvider)
|
|
super().setUp()
|
|
self.request = RequestFactory().get("/")
|
|
self.request.session = Client().session
|
|
self.request.subdomain = None
|
|
|
|
def tearDown(self):
|
|
super().tearDown()
|
|
sentry.identity.unregister(DummyProvider)
|
|
|
|
@cached_property
|
|
def view(self):
|
|
return OAuth2LoginView(
|
|
authorize_url="https://example.org/oauth2/authorize",
|
|
client_id=123456,
|
|
scope="all-the-things",
|
|
)
|
|
|
|
def test_simple(self):
|
|
pipeline = IdentityProviderPipeline(request=self.request, provider_key="dummy")
|
|
response = self.view.dispatch(self.request, pipeline)
|
|
|
|
assert response.status_code == 302
|
|
assert response["Location"].startswith("https://example.org/oauth2/authorize")
|
|
redirect_url = urlparse(response["Location"])
|
|
query = parse_qs(redirect_url.query)
|
|
|
|
assert query["client_id"][0] == "123456"
|
|
assert query["redirect_uri"][0] == "http://testserver/extensions/default/setup/"
|
|
assert query["response_type"][0] == "code"
|
|
assert query["scope"][0] == "all-the-things"
|
|
assert "state" in query
|
|
|
|
def test_customer_domains(self):
|
|
self.request.subdomain = "albertos-apples"
|
|
pipeline = IdentityProviderPipeline(request=self.request, provider_key="dummy")
|
|
response = self.view.dispatch(self.request, pipeline)
|
|
|
|
assert response.status_code == 302
|
|
assert response["Location"].startswith("https://example.org/oauth2/authorize")
|
|
redirect_url = urlparse(response["Location"])
|
|
query = parse_qs(redirect_url.query)
|
|
|
|
assert query["client_id"][0] == "123456"
|
|
assert query["redirect_uri"][0] == "http://testserver/extensions/default/setup/"
|
|
assert query["response_type"][0] == "code"
|
|
assert query["scope"][0] == "all-the-things"
|
|
assert "state" in query
|