Esempio n. 1
0
    def oidc_callback(self):
        """
        Exchange the auth code for actual credentials,
        then redirect to the originally requested page.
        """
        # retrieve session and callback variables
        try:
            session_csrf_token = session.pop('oidc_csrf_token')

            state = json.loads(request.args['state'])
            csrf_token = state['csrf_token']
            destination = state['destination']

            code = request.args['code']
        except (KeyError, ValueError):
            logger.debug("Can't retrieve CSRF token, state, or code",
                         exc_info=True)
            return self.oidc_error()

        # check callback CSRF token passed to IdP
        # against session CSRF token held by user
        if csrf_token != session_csrf_token:
            logger.debug("CSRF token mismatch")
            return self.oidc_error()

        # make a request to IdP to exchange the auth code for OAuth credentials
        flow = self.flow_for_request()
        if 'scope' in request.args:
            scopes = set(util.string_to_scopes(request.args['scope']))
            scopes |= set(util.string_to_scopes(flow.scope))
            flow.scope = util.scopes_to_string(scopes)
        credentials = flow.step2_exchange(code, http=self.http)
        id_token = credentials.id_token
        if not self.is_id_token_valid(id_token):
            logger.debug("Invalid ID token")
            # None will allow all domains otherwise limit down to the specific domain.
            if self.google_apps_domain is not None:
                if not isinstance(self.google_apps_domain, list):
                    self.google_apps_domain = [self.google_apps_domain]
                if id_token.get('hd') not in self.google_apps_domain:
                    return self.oidc_error(
                        "You must log in with an account from one of the following domains: {0}"
                        .format(', '.join(self.google_apps_domain)),
                        self.WRONG_GOOGLE_APPS_DOMAIN)
            return self.oidc_error()

        # store credentials by subject
        # when Google is the IdP, the subject is their G+ account number
        self.credentials_store[id_token['sub']] = credentials

        # set a persistent signed cookie containing the ID token
        # and redirect to the final destination
        # TODO: validate redirect destination
        response = self.redirect_to(destination)
        self.set_cookie_id_token(id_token)
        return response
Esempio n. 2
0
    def test_conversion(self):
        cases = [
            (['a', 'b'], ['a', 'b']),
            ('', []),
            ('a', ['a']),
            ('a b c d e f', ['a', 'b', 'c', 'd', 'e', 'f']),
        ]

        for case, expected in cases:
            self.assertEqual(expected, util.string_to_scopes(case))