Пример #1
0
    def test_valid_redirect_url(self):
        url = sso.sso_redirect_url(
            nonce=self.nonce,
            secret=self.secret,
            email=self.email,
            external_id=self.external_id,
            username=self.username,
            name=self.name,
            avatar_url=self.avatar_url,
            bio=self.bio)

        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_plus(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,
            'name': self.name,
            'avatar_url': self.avatar_url,
            'bio': self.bio
        })
Пример #2
0
    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,
            },
        )
Пример #3
0
def discourse_sso_login():
    if not main.app.config["ENABLE_SSO_FOR_DISCOURSE"]:
        return "Single-sign on for discourse forum is disabled by Exeris server configuration"

    payload = request.args["sso"]
    signature = request.args["sig"]
    sso_secret = main.app.config["DISCOURSE_SSO_SECRET"]

    try:
        sso_validate(payload, signature, sso_secret)
    except DiscourseError as e:
        return str(e.args)

    if g.player.confirmed_at is None:
        return "The email address of the {} is not yet confirmed".format(g.player.id)

    base64_encoded_payload = urllib.parse.unquote(payload)
    payload = urllib.parse.parse_qs(base64.b64decode(base64_encoded_payload).decode("utf8"))

    response_payload = sso_payload(sso_secret,
                                   nonce=payload["nonce"][0],
                                   email=g.player.email,
                                   external_id=g.player.id,
                                   username=g.player.id
                                   )

    return redirect(payload["return_sso_url"][0] + "?" + response_payload)
Пример #4
0
def sso(request):
    try:
        payload = request.GET.get('sso')
        sig = request.GET.get('sig')
        nonce = sso_validate(payload, sig, settings.DISCOURSE_SSO_SECRET)

        # Workaround for bug in pydiscourse.sso: It creates a nonce which
        # looks like "6ec2d11456ecba485823f791a468a4cd&return_sso_url",
        # so just remove the &return_sso_url
        if '&' in nonce:
            nonce = nonce.split('&')[0]

        # FIXME Add nickname to ldap as seperate field
        nickname = re.sub(r'(.+)\s\((.+)\)$', r'\1',
                          request.user.get_ldapuser().display_name)
        url = sso_redirect_url(nonce,
                               settings.DISCOURSE_SSO_SECRET,
                               request.user.email,
                               request.user.username,
                               request.user.username,
                               name=nickname.encode('utf-8'))

    except DiscourseError:
        return HttpResponse(status=400)
    return redirect(settings.DISCOURSE_URL + url)
Пример #5
0
    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 = base64.decodestring(payload)
        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
        })
Пример #6
0
def view():
    if 'nonce' in request.args:
        nonce = request.args.get('nonce')
    else:
        payload = request.args.get('sso')
        signature = request.args.get('sig')
        try:
            nonce = sso_validate(payload, signature, SECRET)
        except DiscourseError as e:
            return render_template('error.html', error=e)
        nonce = nonce.rstrip('&return_sso_url')  # IDK???!!!!

    return render_template('view.html', nonce=nonce)
Пример #7
0
    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)
Пример #8
0
def perform_discourse_login(user):
    plugin_config = helpers.get_plugin_config('colab_discourse')
    prefix = helpers.get_plugin_prefix('colab_discourse', regex=False)
    base_url = Site.objects.get_current().domain
    base_url = "{}/{}".format(base_url, prefix)
    url = base_url + "/session/sso"

    response = requests.get(url, allow_redirects=False)
    if response.status_code == 302:
        location = response.headers.get("Location")

        regex = re.compile(r"sso=(.+)&sig=(.+)")
        matches = regex.search(location)
        payload, signature = matches.groups()
        secret = plugin_config.get('sso_secret')

        nonce = sso_validate(payload, signature, secret)
        url = sso_redirect_url(nonce, secret, user.email,
                               user.id, user.username,
                               name=user.first_name.encode('utf-8'))
        response = requests.get(base_url + url, allow_redirects=False)
        return response
    return None
Пример #9
0
def discourse_login(sender, user, request, **kwargs):
    upstream = settings.DISCOURSE_UPSTREAM
    upstream = upstream[:-1] if upstream[-1] == '/' else upstream

    response = requests.get(upstream + '/session/sso', allow_redirects=False)
    if response.status_code == 302:
        location = response.headers['Location']

        regex = re.compile(r'sso=(.+)&sig=(.+)')
        matches = regex.search(location)
        payload, signature = matches.groups()
        secret = settings.DISCOURSE_SSO_SECRET

        nonce = sso_validate(payload, signature, secret)
        url = sso_redirect_url(nonce,
                               secret,
                               user.email,
                               user.id,
                               user.username,
                               name=user.get_full_name().encode('utf-8'))
        response = requests.get(upstream + url, allow_redirects=False)
        t_cookie = response.cookies.get('_t')

        request.COOKIES['_t'] = t_cookie
Пример #10
0
 def test_valid_nonce(self):
     nonce = sso.sso_validate(self.payload, self.signature, self.secret)
     self.assertEqual(nonce, self.nonce)
Пример #11
0
 def test_invalid_signature(self):
     with self.assertRaises(DiscourseError):
         sso.sso_validate(self.payload, 'notavalidsignature', self.secret)