77 lines
2.7 KiB
Python
77 lines
2.7 KiB
Python
from base64 import b64decode
|
|
|
|
import unittest
|
|
|
|
from urllib.parse import unquote
|
|
from urllib.parse import urlparse, parse_qs
|
|
|
|
from pydiscourse import sso
|
|
from pydiscourse.exceptions import DiscourseError
|
|
|
|
|
|
class SSOTestCase(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
# values from https://meta.discourse.org/t/official-single-sign-on-for-discourse/13045
|
|
self.secret = "d836444a9e4084d5b224a60c208dce14"
|
|
self.nonce = "cb68251eefb5211e58c00ff1395f0c0b"
|
|
self.payload = "bm9uY2U9Y2I2ODI1MWVlZmI1MjExZTU4YzAwZmYxMzk1ZjBjMGI%3D%0A"
|
|
self.signature = "2828aa29899722b35a2f191d34ef9b3ce695e0e6eeec47deb46d588d70c7cb56"
|
|
|
|
self.name = u"sam"
|
|
self.username = u"samsam"
|
|
self.external_id = u"hello123"
|
|
self.email = u"test@test.com"
|
|
self.redirect_url = u"/session/sso_login?sso=bm9uY2U9Y2I2ODI1MWVlZmI1MjExZTU4YzAwZmYxMzk1ZjBjMGImbmFtZT1z%0AYW0mdXNlcm5hbWU9c2Ftc2FtJmVtYWlsPXRlc3QlNDB0ZXN0LmNvbSZleHRl%0Acm5hbF9pZD1oZWxsbzEyMw%3D%3D%0A&sig=1c884222282f3feacd76802a9dd94e8bc8deba5d619b292bed75d63eb3152c0b"
|
|
|
|
def test_missing_args(self):
|
|
with self.assertRaises(DiscourseError):
|
|
sso.sso_validate(None, self.signature, self.secret)
|
|
|
|
with self.assertRaises(DiscourseError):
|
|
sso.sso_validate("", self.signature, self.secret)
|
|
|
|
with self.assertRaises(DiscourseError):
|
|
sso.sso_validate(self.payload, None, self.secret)
|
|
|
|
def test_invalid_signature(self):
|
|
with self.assertRaises(DiscourseError):
|
|
sso.sso_validate(self.payload, "notavalidsignature", self.secret)
|
|
|
|
def test_valid_nonce(self):
|
|
nonce = sso.sso_validate(self.payload, self.signature, self.secret)
|
|
self.assertEqual(nonce, self.nonce)
|
|
|
|
def test_valid_redirect_url(self):
|
|
url = sso.sso_redirect_url(
|
|
self.nonce,
|
|
self.secret,
|
|
self.email,
|
|
self.external_id,
|
|
self.username,
|
|
name="sam",
|
|
)
|
|
|
|
self.assertIn("/session/sso_login", url[:20])
|
|
|
|
# check its valid, using our own handy validator
|
|
params = parse_qs(urlparse(url).query)
|
|
payload = params["sso"][0]
|
|
sso.sso_validate(payload, params["sig"][0], self.secret)
|
|
|
|
# check the params have all the data we expect
|
|
payload = b64decode(payload.encode("utf-8")).decode("utf-8")
|
|
payload = unquote(payload)
|
|
payload = dict((p.split("=") for p in payload.split("&")))
|
|
|
|
self.assertEqual(
|
|
payload,
|
|
{
|
|
"username": self.username,
|
|
"nonce": self.nonce,
|
|
"external_id": self.external_id,
|
|
"name": self.name,
|
|
"email": self.email,
|
|
},
|
|
)
|