def do_POST(self):
        """Serve a POST request."""
        if not self.path == self.saml_post_path:
            self._bad_request()
            return

        length = int(self.headers['Content-Length'])
        data = self.rfile.read(length)
        query = urlparse.parse_qs(data)
        res = Response(
            query['SAMLResponse'].pop(),
            self.settings['idp_cert_fingerprint'],
            )
        valid = res.is_valid()
        name_id = res.name_id
        if valid:
            msg = 'The identity of {name_id} has been verified'.format(
                name_id=name_id,
                )
            self._serve_msg(200, msg)
        else:
            msg = '{name_id} is not authorized to use this resource'.format(
                name_id=name_id,
                )
            self._serve_msg(401, msg)
    def test_is_valid_simple(self):
        encoded_response = base64.b64encode(test_response)
        res = Response(
            response=encoded_response,
            signature='foo signature',
            )

        def fake_clock():
            return datetime(2004, 12, 05, 9, 18, 45, 462796)

        fake_verifier = fudge.Fake(
            'verifier',
            callable=True,
            )
        fake_verifier.times_called(1)
        fake_verifier.with_args(res._document, 'foo signature')

        fake_verifier.returns(True)

        msg = res.is_valid(
            _clock=fake_clock,
            _verifier=fake_verifier,
            )

        eq(msg, True)
def logged_in_from_adfs():
    app.logger.info('User logged in via ADFS')
    SAMLResponse = request.values['SAMLResponse']

    try:
        res = ADFSResponse(SAMLResponse, app.adfs_settings["idp_cert_fingerprint"])

        res.decrypt(app.adfs_settings["sp_private_key"])
        valid = res.is_valid()

        if not valid:
            app.logger.error('Invalid response from ADFS')
            abort(404)

        def to_unicode(in_str):
            return in_str.encode("utf-8")

        name_id = to_unicode(res.name_id)
        ident = get_attribute_or_404(res, "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname")
        name = to_unicode(get_attribute_or_404(res, "http://schemas.xmlsoap.org/claims/CommonName"))
        email = to_unicode(
            get_attribute_or_404(res, "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"))

        app.logger.info('Logging in: name_id=%s name=%s ident=%s email=%s', name_id, name, ident, email)
        data = {"misc": {"name": name,
                         "email": email,
                         "ident": ident}}

        claims = adfs_helper.parse_claims(res._document)
        app.logger.info('Claims in SAML response: %s', claims)

        roles = adfs_helper.extract_roles(claims)
        app.logger.info('Requested roles parsed from claims: %s', roles)

        auth_user = authentication.login_adfs_user_by_private_id(ident, data)
        user_roles = authentication.update_user_roles(auth_user.user_id, roles)
        auth_user.roles = user_roles
        app.logger.info('User roles after update: %s', user_roles)

        login_user(auth_user, remember=True)
        # Check if the user wants to redirect to a specific page
        redirect_target = get_redirect_target_from_cookie(request)
        response = make_response(redirect(redirect_target or request.args.get('next') or '/'))
        invalidate_redirect_target_cookie(response)

        set_cookie(response, 'auth_token', make_auth_token(auth_user.user_id))

        # set authentication type cookie
        set_auth_type_cookie(response, "active_directory")

        return response
    except Exception as e:
        app.logger.error('Logging failed: %s', e)
        abort(404, 'Ugyldig innlogging.')