def test_is_valid_simple(self):
        encoded_response = base64.b64encode(test_response)
        fake_signature = 'foo signature'
        res = Response(
            response=encoded_response,
            signature='foo signature',
        )

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

        private_key_file = "/tmp/tes.txt"
        idp_cert_filename = "/tmp/junk.txt"
        fake_verifier = fudge.Fake(
            'verifier',
            callable=True,
        )
        fake_verifier.times_called(1)
        fake_verifier.with_args(res._document, fake_signature,
                                idp_cert_filename, private_key_file)
        fake_verifier.returns((True, "<xml></xml>"))

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

        eq(msg, True)
    def test_is_valid_simple(self):
        encoded_response = base64.b64encode(test_response)
        fake_signature = 'foo signature'
        res = Response(
            response=encoded_response,
            signature='foo signature',
            )

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

        private_key_file = "/tmp/tes.txt"
        idp_cert_filename = "/tmp/junk.txt"
        fake_verifier = fudge.Fake(
            'verifier',
            callable=True,
            )
        fake_verifier.times_called(1)
        fake_verifier.with_args(res._document, fake_signature, idp_cert_filename, private_key_file)
        fake_verifier.returns((True, "<xml></xml>"))


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

        eq(msg, True)
    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 logged_in():
    # IDPorten redirects to this URL if all ok with login
    app.logger.info("User logged in via ID-porten: request.values=%s",
                    request.values)
    SAMLResponse = request.values['SAMLResponse']

    res = IdpResponse(
        SAMLResponse,
        "TODO: remove signature parameter"
    )

    # Decrypt response from IDPorten with our private key, and make sure that the response is valid
    # (it was encrypted with same key)
    valid = res.is_valid(app.idporten_settings["idp_cert_file"], app.idporten_settings["private_key_file"])
    if valid:
        national_id_number = res.get_decrypted_assertion_attribute_value("uid")[0]
        idporten_parameters = {
            "session_index": res.get_session_index(),
            "name_id": res.name_id
        }

        auth_user = authentication.login_idporten_user_by_private_id(national_id_number,
                                                                     idporten_parameters)
        login_user(auth_user, remember=True)

        # Force the user to fill in the profile if unregistered
        if not auth_user.is_registered():
            app.logger.info("Logged in: %s Uregistrert bruker (%s)",
                            datetime.now().isoformat(),
                            national_id_number[:6])
            response = make_response(redirect("/profile"))
        else:
            app.logger.info("Logged in: %s %s %s (%s)",
                            datetime.now().isoformat(),
                            auth_user.first_name,
                            auth_user.last_name,
                            national_id_number[:6])

            # 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))
        return response
    else:
        abort(404, 'Ugyldig innlogging.')
Example #5
0
def logged_in():
    app.logger.info("User logged in via ID-porten: request.values=%s",
                    request.values)
    SAMLResponse = request.values['SAMLResponse']

    res = IdpResponse(
        SAMLResponse,
        "TODO: remove signature parameter"
    )
    valid = res.is_valid(settings["idp_cert_file"], settings["private_key_file"])
    if valid:
        national_id_number = res.get_decrypted_assertion_attribute_value("uid")[0]
        idporten_parameters = {
            "session_index": res.get_session_index(),
            "name_id": res.name_id
        }

        auth_user = authentication.login_user_by_private_id(national_id_number,
                                                            idporten_parameters)

        # Force the user to fill in the profile if unregistered
        if not auth_user.is_registered():
            app.logger.info("Logged in: %s Uregistrert bruker (%s)",
                            datetime.now().isoformat(),
                            national_id_number[:6])
            response = make_response(redirect("/profile"))
        else:
            app.logger.info("Logged in: %s %s %s (%s)",
                            datetime.now().isoformat(),
                            auth_user.first_name,
                            auth_user.last_name,
                            national_id_number[:6])

            # Check if the user wants to redirect to a specific page
            redirect_target = request.cookies.get("redirect_target", None)
            if not redirect_target or not is_safe_url(redirect_target):
                redirect_target = None
            response = make_response(
                redirect(redirect_target or request.args.get('next') or '/'))
            # Invalidate the redirect cookie by giving it a past expiry date
            response.set_cookie("redirect_target", "", expires=0)

        set_cookie(response, 'auth_token', make_auth_token(auth_user.user_id))
        return response
    else:
        abort(404, 'Ugyldig innlogging.')
    def test_get_name_id_simple(self):
        encoded_response = base64.b64encode(test_response)
        res = Response(
            response=encoded_response,
            signature=None,
        )
        name_id = res.name_id

        eq('3f7b3dcf-1674-4ecd-92c8-1544f346baf8', name_id)
def logged_in():
    print "USER LOGGED IN VIA IDPORTEN"
    print request.values
    SAMLResponse = request.values['SAMLResponse']

    res = Response(
        SAMLResponse,
        "TODO: remove signature parameter"
        )
    valid = res.is_valid(settings["idp_cert_file"], settings["private_key_file"])

    uid = res.get_decrypted_assertion_attribute_value("uid")
    name_id = res.name_id
    print "UID", uid
    print "NAME ID: ", name_id
    print "Session index: ", res.get_session_index()
    user_info["uid"] = uid
    user_info["name_id"] = name_id
    user_info["session_index"] = res.get_session_index()

    return render_template('home.html', decrypted = res.decrypted, uid = uid)
Example #8
0
    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_current_time_on_or_after(self):
        encoded_response = base64.b64encode(test_response)
        res = Response(
            response=encoded_response,
            signature=None,
        )

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

        msg = assert_raises(
            ResponseValidationError,
            res.is_valid,
            _clock=fake_clock,
        )

        eq(
            str(msg),
            ('There was a problem validating the response: Current time is ' +
             'on or after NotOnOrAfter condition'),
        )
    def test__init__(self):
        fake_base64 = fudge.Fake('base64')
        fake_base64.remember_order()
        decode = fake_base64.expects('b64decode')
        decode.with_args('foo response')
        decode.returns('foo decoded response')

        fake_etree = fudge.Fake('etree')
        fake_etree.remember_order()
        from_string = fake_etree.expects('fromstring')
        from_string.with_args('foo decoded response')
        from_string.returns('foo document')

        res = Response(
            response='foo response',
            signature='foo signature',
            _base64=fake_base64,
            _etree=fake_etree,
        )

        eq(res._document, 'foo document')
        eq(res._signature, 'foo signature')
def logged_in():
    print "USER LOGGED IN VIA IDPORTEN"
    print request.values
    SAMLResponse = request.values['SAMLResponse']

    res = Response(SAMLResponse, "TODO: remove signature parameter")
    valid = res.is_valid(settings["idp_cert_file"],
                         settings["private_key_file"])

    uid = res.get_decrypted_assertion_attribute_value("uid")
    name_id = res.name_id
    print "UID", uid
    print "NAME ID: ", name_id
    print "Session index: ", res.get_session_index()
    user_info["uid"] = uid
    user_info["name_id"] = name_id
    user_info["session_index"] = res.get_session_index()

    return render_template('home.html', decrypted=res.decrypted, uid=uid)
    def test_is_valid_not_on_or_after_missing(self):
        response = """<samlp:Response
   xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
   xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
   ID="identifier_2"
   InResponseTo="identifier_1"
   Version="2.0"
   IssueInstant="2004-12-05T09:22:05Z"
   Destination="https://sp.example.com/SAML2/SSO/POST">
   <saml:Issuer>https://idp.example.org/SAML2</saml:Issuer>
   <samlp:Status>
     <samlp:StatusCode
       Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
   </samlp:Status>
   <saml:Assertion
     xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
     ID="identifier_3"
     Version="2.0"
     IssueInstant="2004-12-05T09:22:05Z">
     <saml:Issuer>https://idp.example.org/SAML2</saml:Issuer>
     <ds:Signature
       xmlns:ds="http://www.w3.org/2000/09/xmldsig#">foo signature</ds:Signature>
     <saml:Subject>
       <saml:NameID
         Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">
         3f7b3dcf-1674-4ecd-92c8-1544f346baf8
       </saml:NameID>
       <saml:SubjectConfirmation
         Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
         <saml:SubjectConfirmationData
           InResponseTo="identifier_1"
           Recipient="https://sp.example.com/SAML2/SSO/POST"
           NotOnOrAfter="2004-12-05T09:27:05Z"/>
       </saml:SubjectConfirmation>
     </saml:Subject>
     <saml:Conditions
       NotBefore="2004-12-05T09:27:05Z">
       <saml:AudienceRestriction>
         <saml:Audience>https://sp.example.com/SAML2</saml:Audience>
       </saml:AudienceRestriction>
     </saml:Conditions>
     <saml:AuthnStatement
       AuthnInstant="2004-12-05T09:22:00Z"
       SessionIndex="identifier_3">
       <saml:AuthnContext>
         <saml:AuthnContextClassRef>
           urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
        </saml:AuthnContextClassRef>
       </saml:AuthnContext>
     </saml:AuthnStatement>
   </saml:Assertion>
 </samlp:Response>
"""
        encoded_response = base64.b64encode(response)
        res = Response(
            response=encoded_response,
            signature=None,
        )
        msg = assert_raises(
            ResponseConditionError,
            res.is_valid,
        )

        eq(
            str(msg),
            ('There was a problem validating a condition: Did not find ' +
             'NotOnOrAfter condition'),
        )
    def test_get_name_id_none(self):
        response = """<samlp:Response
   xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
   xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
   ID="identifier_2"
   InResponseTo="identifier_1"
   Version="2.0"
   IssueInstant="2004-12-05T09:22:05Z"
   Destination="https://sp.example.com/SAML2/SSO/POST">
   <saml:Issuer>https://idp.example.org/SAML2</saml:Issuer>
   <samlp:Status>
     <samlp:StatusCode
       Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
   </samlp:Status>
   <saml:Assertion
     xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
     ID="identifier_3"
     Version="2.0"
     IssueInstant="2004-12-05T09:22:05Z">
     <saml:Issuer>https://idp.example.org/SAML2</saml:Issuer>
     <ds:Signature
       xmlns:ds="http://www.w3.org/2000/09/xmldsig#">...</ds:Signature>
     <saml:Subject>
       <saml:SubjectConfirmation
         Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
         <saml:SubjectConfirmationData
           InResponseTo="identifier_1"
           Recipient="https://sp.example.com/SAML2/SSO/POST"
           NotOnOrAfter="2004-12-05T09:27:05Z"/>
       </saml:SubjectConfirmation>
     </saml:Subject>
     <saml:Conditions
       NotBefore="2004-12-05T09:17:05Z"
       NotOnOrAfter="2004-12-05T09:27:05Z">
       <saml:AudienceRestriction>
         <saml:Audience>https://sp.example.com/SAML2</saml:Audience>
       </saml:AudienceRestriction>
     </saml:Conditions>
     <saml:AuthnStatement
       AuthnInstant="2004-12-05T09:22:00Z"
       SessionIndex="identifier_3">
       <saml:AuthnContext>
         <saml:AuthnContextClassRef>
           urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
        </saml:AuthnContextClassRef>
       </saml:AuthnContext>
     </saml:AuthnStatement>
   </saml:Assertion>
 </samlp:Response>
"""
        encoded_response = base64.b64encode(response)
        res = Response(
            response=encoded_response,
            signature=None,
        )
        msg = assert_raises(
            ResponseNameIDError,
            res._get_name_id,
        )

        eq(
            str(msg),
            ('There was a problem getting the name ID: Did not find a name ' +
             'ID'),
        )