예제 #1
0
    def test_registering_new_device_view(self):
        """Test that the HTML view works."""
        hass = MagicMock()

        with tempfile.NamedTemporaryFile() as fp:
            hass.config.path.return_value = fp.name
            fp.close()
            service = html5.get_service(hass, {})

            assert service is not None

            # assert hass.called
            assert len(hass.mock_calls) == 3

            view = hass.mock_calls[1][1][0]
            assert view.json_path == fp.name
            assert view.registrations == {}

            builder = EnvironBuilder(method='POST',
                                     data=json.dumps(SUBSCRIPTION_1))
            Request = request_class()
            resp = view.post(Request(builder.get_environ()))

            expected = {
                'unnamed device': SUBSCRIPTION_1,
            }

            assert resp.status_code == 200, resp.response
            assert view.registrations == expected
            with open(fp.name) as fpp:
                assert json.load(fpp) == expected
    def test_10_api_endpoint(self):
        fixed = "ebedeeefegeheiej"
        otpkey = "cc17a4d77eaed96e9d14b5c87a02e718"
        uid = "000000000000"
        otps = ["ebedeeefegeheiejtjtrutblehenfjljrirgdihrfuetljtt",
                "ebedeeefegeheiejlekvlrlkrcluvctenlnnjfknrhgtjned",
                "ebedeeefegeheiejktudedbktcnbuntrhdueikggtrugckij",
                "ebedeeefegeheiejjvjncbnffdrvjcvrbgdfufjgndfetieu",
                "ebedeeefegeheiejdruibhvlvktcgfjiruhltketifnitbuk"
        ]

        token = init_token({"type": "yubikey",
                            "otpkey": otpkey,
                            "otplen": len(otps[0]),
                            "yubikey.prefix": fixed,
                            "serial": "UBAM12345678_1"})

        builder = EnvironBuilder(method='GET',
                                 headers={})
        env = builder.get_environ()
        # Set the remote address so that we can filter for it
        env["REMOTE_ADDR"] = "10.0.0.1"
        g.client_ip = env["REMOTE_ADDR"]
        req = Request(env)
        nonce = "random nonce"
        apiid = "hallo"
        apikey = "1YMEbMZijD3DzL21UfKGnOOI13c="
        set_privacyidea_config("yubikey.apiid.{0!s}".format(apiid), apikey)
        req.all_data = {'id': apiid,
                        "otp": otps[0],
                        "nonce": nonce}
        text_type, result = YubikeyTokenClass.api_endpoint(req, g)
        self.assertEqual(text_type, "plain")
        self.assertTrue("status=OK" in result, result)
        self.assertTrue("nonce={0!s}".format(nonce) in result, result)
예제 #3
0
    def test_callback_view_no_jwt(self):
        """Test that the notification callback view works without JWT."""
        hass = MagicMock()

        m = mock_open()
        with patch(
                'homeassistant.components.notify.html5.open', m, create=True
        ):
            hass.config.path.return_value = 'file.conf'
            service = html5.get_service(hass, {})

            assert service is not None

            # assert hass.called
            assert len(hass.mock_calls) == 3

            view = hass.mock_calls[2][1][0]

            builder = EnvironBuilder(method='POST', data=json.dumps({
                'type': 'push',
                'tag': '3bc28d69-0921-41f1-ac6a-7a627ba0aa72'
            }))
            Request = request_class()
            resp = view.post(Request(builder.get_environ()))

            assert resp.status_code == 401, resp.response
예제 #4
0
    def test_redirect_url_error_1(self, mock_validate_email):
        """
        Tests the user is redirected to appropriate location
        """

        # Build test environment
        builder = EnvironBuilder(method='POST',
                                 data={'name': 'Valid Guy',
                                       'email': '*****@*****.**',
                                       'redirect': 'http://www.example.com',
                                       'last_name': '',
                                       'token': conf.TOKEN})
        env = builder.get_environ()
        req = Request(env)

        # Mock validate email so returns false in Travis
        # Not technically necessary because this will return false in Travis
        # regardless since it can't find the SMTP server, but kept here for
        # consistency
        mock_validate_email.return_value = False

        # Create app and mock redirect
        app = handler.create_app()
        werkzeug.utils.redirect = Mock('werkzeug.utils.redirect')
        # Mock sendmail function so it doesn't send an actual email
        smtplib.SMTP.sendmail = Mock('smtplib.SMTP.sendmail')
        app.on_form_page(req)

        werkzeug.utils.redirect.assert_called_with(
            'http://www.example.com?error=1&message=Invalid+Email',
            code=302)
예제 #5
0
    def test_registering_new_device_view(self):
        """Test that the HTML view works."""
        hass = MagicMock()

        m = mock_open()
        with patch(
                'homeassistant.components.notify.html5.open', m, create=True
        ):
            hass.config.path.return_value = 'file.conf'
            service = html5.get_service(hass, {})

            assert service is not None

            # assert hass.called
            assert len(hass.mock_calls) == 3

            view = hass.mock_calls[1][1][0]
            assert view.json_path == hass.config.path.return_value
            assert view.registrations == {}

            builder = EnvironBuilder(method='POST',
                                     data=json.dumps(SUBSCRIPTION_1))
            Request = request_class()
            resp = view.post(Request(builder.get_environ()))

            expected = {
                'unnamed device': SUBSCRIPTION_1,
            }

            assert resp.status_code == 200, resp.response
            assert view.registrations == expected
            handle = m()
            assert json.loads(handle.write.call_args[0][0]) == expected
예제 #6
0
    def test_15_reset_password(self):
        builder = EnvironBuilder(method='POST',
                                 data={'user': "******",
                                       "realm": self.realm1},
                                 headers={})
        env = builder.get_environ()
        # Set the remote address so that we can filter for it
        env["REMOTE_ADDR"] = "10.0.0.1"
        req = Request(env)
        # Set a mangle policy to change the username
        # and only use the last 4 characters of the username
        set_policy(name="recover",
                   scope=SCOPE.USER,
                   action="%s" % ACTION.RESYNC)
        g.policy_object = PolicyClass()
        req.all_data = {"user": "******", "realm": self.realm1}
        # There is a user policy without password reset, so an exception is
        # raised
        self.assertRaises(PolicyError, check_anonymous_user, req,
                          ACTION.PASSWORDRESET)

        # The password reset is allowed
        set_policy(name="recover",
                   scope=SCOPE.USER,
                   action="%s" % ACTION.PASSWORDRESET)
        g.policy_object = PolicyClass()
        r = check_anonymous_user(req, ACTION.PASSWORDRESET)
        self.assertEqual(r, True)
예제 #7
0
    def test_03_no_detail_on_success(self):
        builder = EnvironBuilder(method='POST',
                                 data={'serial': "HOTP123435"},
                                 headers={})
        env = builder.get_environ()
        # Set the remote address so that we can filter for it
        env["REMOTE_ADDR"] = "10.0.0.1"
        req = Request(env)
        # The response contains the token type SPASS
        res = {"jsonrpc": "2.0",
               "result": {"status": True,
                          "value": True},
               "version": "privacyIDEA test",
               "id": 1,
               "detail": {"message": "matching 1 tokens",
                          "serial": "HOTP123456",
                          "type": "hotp"}}
        resp = Response(json.dumps(res))

        # Set a policy, that does not allow the detail on success
        set_policy(name="pol2",
                   scope=SCOPE.AUTHZ,
                   action="no_detail_on_success", client="10.0.0.0/8")
        g.policy_object = PolicyClass()

        new_response = no_detail_on_success(req, resp)
        jresult = json.loads(new_response.data)
        self.assertTrue("detail" not in jresult, jresult)
        delete_policy("pol2")
예제 #8
0
    def test_13_remote_user(self):
        g.logged_in_user = {"username": "******",
                            "role": "admin"}
        builder = EnvironBuilder(method='POST',
                                 data={'serial': "OATH123456"},
                                 headers={})
        env = builder.get_environ()
        # Set the remote address so that we can filter for it
        env["REMOTE_ADDR"] = "10.0.0.1"
        env["REMOTE_USER"] = "******"
        req = Request(env)

        # A user, for whom the login via REMOTE_USER is allowed.
        set_policy(name="ruser",
                   scope=SCOPE.WEBUI,
                   action="%s=%s" % (ACTION.REMOTE_USER, REMOTE_USER.ACTIVE))
        g.policy_object = PolicyClass()

        r = is_remote_user_allowed(req)
        self.assertEqual(r, [REMOTE_USER.ACTIVE])

        # Login for the REMOTE_USER is not allowed.
        # Only allowed for user "super", but REMOTE_USER=admin
        set_policy(name="ruser",
                   scope=SCOPE.WEBUI,
                   action="%s=%s" % (ACTION.REMOTE_USER, REMOTE_USER.ACTIVE),
                   user="******")
        g.policy_object = PolicyClass()

        r = is_remote_user_allowed(req)
        self.assertEqual(r, [])

        delete_policy("ruser")
예제 #9
0
    def test_14_required_email(self):
        g.logged_in_user = {"username": "******",
                            "role": "admin"}
        builder = EnvironBuilder(method='POST',
                                 data={'serial': "OATH123456"},
                                 headers={})
        env = builder.get_environ()
        # Set the remote address so that we can filter for it
        env["REMOTE_ADDR"] = "10.0.0.1"
        req = Request(env)
        # Set a mangle policy to change the username
        # and only use the last 4 characters of the username
        set_policy(name="email1",
                   scope=SCOPE.REGISTER,
                   action="%s=/.*@mydomain\..*" % ACTION.REQUIREDEMAIL)
        g.policy_object = PolicyClass()
        # request, that matches the policy
        req.all_data = {"email": "*****@*****.**"}
        # This emails is allowed
        r = required_email(req)
        self.assertTrue(r)

        # This email is not allowed
        req.all_data = {"email": "*****@*****.**"}
        # This emails is allowed
        self.assertRaises(RegistrationError, required_email, req)

        delete_policy("email1")
        g.policy_object = PolicyClass()
        # Without a policy, this email can register
        req.all_data = {"email": "*****@*****.**"}
        # This emails is allowed
        r = required_email(req)
        self.assertTrue(r)
예제 #10
0
    def test_08_encrypt_pin(self):
        g.logged_in_user = {"username": "******",
                            "role": "admin"}
        builder = EnvironBuilder(method='POST',
                                 data={'serial': "OATH123456"},
                                 headers={})
        env = builder.get_environ()
        # Set the remote address so that we can filter for it
        env["REMOTE_ADDR"] = "10.0.0.1"
        req = Request(env)

        # Set a policy that defines the PIN to be encrypted
        set_policy(name="pol1",
                   scope=SCOPE.ENROLL,
                   action=ACTION.ENCRYPTPIN)
        g.policy_object = PolicyClass()

        # request, that matches the policy
        req.all_data = {
                        "user": "******",
                        "realm": "home"}
        encrypt_pin(req)

        # Check, if the tokenlabel was added
        self.assertEqual(req.all_data.get("encryptpin"), "True")
        # finally delete policy
        delete_policy("pol1")
예제 #11
0
    def test_10_check_external(self):
        g.logged_in_user = {"username": "******",
                            "role": "user"}
        builder = EnvironBuilder(method='POST',
                                 data={'serial': "OATH123456"},
                                 headers={})
        env = builder.get_environ()
        req = Request(env)
        g.policy_object = PolicyClass()
        req.all_data = {
                        "user": "******",
                        "realm": "home"}

        # Check success on no definition
        r = check_external(req)
        self.assertTrue(r)

        # Check success with external function
        current_app.config["PI_INIT_CHECK_HOOK"] = \
            "privacyidea.api.lib.prepolicy.mock_success"
        r = check_external(req)
        self.assertTrue(r)

        # Check exception with external function
        current_app.config["PI_INIT_CHECK_HOOK"] = \
            "privacyidea.api.lib.prepolicy.mock_fail"
        self.assertRaises(Exception, check_external, req)
예제 #12
0
    def test_06_set_tokenlabel(self):
        g.logged_in_user = {"username": "******",
                            "role": "admin"}
        builder = EnvironBuilder(method='POST',
                                 data={'serial': "OATH123456"},
                                 headers={})
        env = builder.get_environ()
        # Set the remote address so that we can filter for it
        env["REMOTE_ADDR"] = "10.0.0.1"
        req = Request(env)

        # Set a policy that defines the tokenlabel
        set_policy(name="pol1",
                   scope=SCOPE.ENROLL,
                   action="%s=%s" % (ACTION.TOKENLABEL, "<u>@<r>"))
        set_policy(name="pol2",
                   scope=SCOPE.ENROLL,
                   action="%s=%s" % (ACTION.TOKENISSUER, "myPI"))
        g.policy_object = PolicyClass()

        # request, that matches the policy
        req.all_data = {
                        "user": "******",
                        "realm": "home"}
        init_tokenlabel(req)

        # Check, if the tokenlabel was added
        self.assertEqual(req.all_data.get("tokenlabel"), "<u>@<r>")
        # Check, if the tokenissuer was added
        self.assertEqual(req.all_data.get("tokenissuer"), "myPI")
        # finally delete policy
        delete_policy("pol1")
        delete_policy("pol2")
예제 #13
0
    def test_07_set_random_pin(self):
        g.logged_in_user = {"username": "******",
                            "role": "admin"}
        builder = EnvironBuilder(method='POST',
                                 data={'serial': "OATH123456"},
                                 headers={})
        env = builder.get_environ()
        # Set the remote address so that we can filter for it
        env["REMOTE_ADDR"] = "10.0.0.1"
        req = Request(env)

        # Set a policy that defines the tokenlabel
        set_policy(name="pol1",
                   scope=SCOPE.ENROLL,
                   action="%s=%s" % (ACTION.OTPPINRANDOM, "12"))
        set_policy(name="pinhandling",
                   scope=SCOPE.ENROLL,
                   action="%s=privacyidea.lib.pinhandling.base.PinHandler" %
                          ACTION.PINHANDLING)
        g.policy_object = PolicyClass()

        # request, that matches the policy
        req.all_data = {
                        "user": "******",
                        "realm": "home"}
        init_random_pin(req)

        # Check, if the tokenlabel was added
        self.assertEqual(len(req.all_data.get("pin")), 12)
        # finally delete policy
        delete_policy("pol1")
        delete_policy("pinhandling")
예제 #14
0
    def test_01a_admin_realms(self):
        admin1 = {"username": "******",
                  "role": "admin",
                  "realm": "realm1"}

        admin2 = {"username": "******",
                  "role": "admin",
                  "realm": "realm2"}

        set_policy(name="pol",
                   scope=SCOPE.ADMIN,
                   action="*", adminrealm="realm1")
        g.policy_object = PolicyClass()
        builder = EnvironBuilder(method='POST',
                                 data={'serial': "OATH123456"},
                                 headers={})
        env = builder.get_environ()
        # Set the remote address so that we can filter for it
        env["REMOTE_ADDR"] = "10.0.0.1"
        req = Request(env)
        req.all_data = {}

        # admin1 is allowed to do everything
        g.logged_in_user = admin1
        r = check_base_action(req, action="delete")
        self.assertTrue(r)

        # admin2 is not allowed.
        g.logged_in_user = admin2
        self.assertRaises(PolicyError, check_base_action, req, action="delete")
        delete_policy("pol")
예제 #15
0
    def test_03_check_token_upload(self):
        g.logged_in_user = {"username": "******",
                            "role": "admin"}
        builder = EnvironBuilder(method='POST',
                                 data={'serial': "OATH123456"},
                                 headers={})
        env = builder.get_environ()
        # Set the remote address so that we can filter for it
        env["REMOTE_ADDR"] = "10.0.0.1"
        req = Request(env)
        req.all_data = {"filename": "token.xml"}

        # Set a policy, that does allow the action
        set_policy(name="pol1",
                   scope=SCOPE.ADMIN,
                   action="enrollTOTP, enrollHOTP, %s" % ACTION.IMPORT,
                   client="10.0.0.0/8")
        g.policy_object = PolicyClass()

        # Try to import tokens
        r = check_token_upload(req)
        self.assertTrue(r)

        # The admin can not upload from another IP address
        # An exception is raised
        env["REMOTE_ADDR"] = "192.168.0.1"
        req = Request(env)
        req.all_data = {"filename": "token.xml"}
        self.assertRaises(PolicyError,
                          check_token_upload, req)
        # finally delete policy
        delete_policy("pol1")
예제 #16
0
def test_submit_handler_foreignid(conn):
    values = {'format': 'json', 'client': 'app1key', 'user': '******',
        'duration': str(TEST_1_LENGTH), 'fingerprint': TEST_1_FP, 'bitrate': 192,
        'foreignid': 'foo:123', 'fileformat': 'FLAC'}
    builder = EnvironBuilder(method='POST', data=values)
    handler = SubmitHandler(connect=provider(conn))
    resp = handler.handle(Request(builder.get_environ()))
    assert_equals('application/json; charset=UTF-8', resp.content_type)
    expected = {"status": "ok"}
    assert_json_equals(expected, resp.data)
    assert_equals('200 OK', resp.status)
    query = tables.submission.select().order_by(tables.submission.c.id.desc()).limit(1)
    submission = conn.execute(query).fetchone()
    assert_equals(None, submission['mbid'])
    assert_equals(None, submission['puid'])
    assert_equals(1, submission['foreignid_id'])
    assert_equals(1, submission['format_id'])
    assert_equals(192, submission['bitrate'])
    assert_equals(TEST_1_FP_RAW, submission['fingerprint'])
    assert_equals(TEST_1_LENGTH, submission['length'])
    query = tables.foreignid_vendor.select().order_by(tables.foreignid_vendor.c.id.desc()).limit(1)
    row = conn.execute(query).fetchone()
    assert_equals(1, row['id'])
    assert_equals('foo', row['name'])
    query = tables.foreignid.select().order_by(tables.foreignid.c.id.desc()).limit(1)
    row = conn.execute(query).fetchone()
    assert_equals(1, row['id'])
    assert_equals(1, row['vendor_id'])
    assert_equals('123', row['name'])
예제 #17
0
    def test_07_sign_response(self):
        builder = EnvironBuilder(method='POST',
                                 data={},
                                 headers={})
        env = builder.get_environ()
        env["REMOTE_ADDR"] = "192.168.0.1"
        req = Request(env)
        req.values = {"user": "******",
                      "pass": "******",
                      "nonce": "12345678"}

        res = {"jsonrpc": "2.0",
               "result": {"status": True,
                          "value": True},
               "version": "privacyIDEA test",
               "id": 1}
        resp = Response(json.dumps(res))
        from privacyidea.lib.crypto import Sign
        g.sign_object = Sign("tests/testdata/private.pem",
                             "tests/testdata/public.pem")

        new_response = sign_response(req, resp)
        jresult = json.loads(new_response.data)
        self.assertEqual(jresult.get("nonce"), "12345678")
        self.assertEqual(jresult.get("signature"), "7220461805369685253863294214862525311437731987121534735993146952136348520396812489782945679627890785973634896605293523175424850299832912878523161817380029213546063467888018205435416020286712762804412024065559270543774578319469096483246637875013247101135063221604113204491121777932147776087110152414627230087278622508771143940031542890514380486863296102037208395371717795767683973979032142677315402422403254992482761563612174177151960004042109847122772813717599078313600692433727690239340230353616318691769042290314664126975201679642739717702497638318611217001361093950139025744740660953017413716736691777322916588328")
예제 #18
0
def test_apihandler_ws_error(conn):
    values = {'format': 'json'}
    builder = EnvironBuilder(method='POST', data=values)
    handler = WebServiceErrorHandler(connect=provider(conn))
    resp = handler.handle(Request(builder.get_environ()))
    assert_equals('application/json; charset=UTF-8', resp.content_type)
    expected = {
        "status": "error",
        "error": {
            "message": "invalid API key",
            "code": 4,
        }
    }
    assert_json_equals(expected, resp.data)
    assert_equals('400 BAD REQUEST', resp.status)
    handler = InternalErrorHandler(connect=provider(conn))
    resp = handler.handle(Request(builder.get_environ()))
    assert_equals('application/json; charset=UTF-8', resp.content_type)
    expected = {
        "status": "error",
        "error": {
            "message": "internal error",
            "code": 5,
        }
    }
    assert_json_equals(expected, resp.data)
    assert_equals('500 INTERNAL SERVER ERROR', resp.status)
예제 #19
0
def test_submit_handler_with_meta(conn):
    values = {'format': 'json', 'client': 'app1key', 'user': '******',
        'duration': str(TEST_1_LENGTH), 'fingerprint': TEST_1_FP, 'bitrate': 192,
        'mbid': 'b9c05616-1874-4d5d-b30e-6b959c922d28', 'fileformat': 'FLAC',
        'track': 'Voodoo People',
        'artist': 'The Prodigy',
        'album': 'Music For The Jitled People',
        'albumartist': 'Prodigy',
        'trackno': '2',
        'discno': '3',
        'year': '2030'
    }
    builder = EnvironBuilder(method='POST', data=values)
    handler = SubmitHandler(connect=provider(conn))
    resp = handler.handle(Request(builder.get_environ()))
    assert_equals('application/json; charset=UTF-8', resp.content_type)
    expected = {"status": "ok"}
    assert_json_equals(expected, resp.data)
    assert_equals('200 OK', resp.status)
    query = tables.submission.select().order_by(tables.submission.c.id.desc()).limit(1)
    submission = conn.execute(query).fetchone()
    assert_equals('b9c05616-1874-4d5d-b30e-6b959c922d28', submission['mbid'])
    assert_equals(1, submission['meta_id'])
    row = conn.execute("SELECT * FROM meta WHERE id=1").fetchone()
    expected = {
        'id': 1,
        'track': 'Voodoo People',
        'artist': 'The Prodigy',
        'album': 'Music For The Jitled People',
        'album_artist': 'Prodigy',
        'track_no': 2,
        'disc_no': 3,
        'year': 2030
    }
    assert_equals(expected, dict(row))
예제 #20
0
    def from_values(cls, *args, **kwargs):
        """Create a new request object based on the values provided.  If
        environ is given missing values are filled from there.  This method is
        useful for small scripts when you need to simulate a request from an URL.
        Do not use this method for unittesting, there is a full featured client
        object (:class:`Client`) that allows to create multipart requests,
        support for cookies etc.

        This accepts the same options as the
        :class:`~werkzeug.test.EnvironBuilder`.

        .. versionchanged:: 0.5
           This method now accepts the same arguments as
           :class:`~werkzeug.test.EnvironBuilder`.  Because of this the
           `environ` parameter is now called `environ_overrides`.

        :return: request object
        """
        from werkzeug.test import EnvironBuilder
        charset = kwargs.pop('charset', cls.charset)
        kwargs['charset'] = charset
        builder = EnvironBuilder(*args, **kwargs)
        try:
            return builder.get_request(cls)
        finally:
            builder.close()
예제 #21
0
    def test_send_email_default(self, mock_validate_email):
        """
        Tests that the form is sent to the correct default address when
        the 'send_to' field is set to an empty string.

        Returns true if the form has been sent to [email protected]
        Errors out if unsuccessful
        """
        builder = EnvironBuilder(method='POST',
                                 data={'name': 'Valid Guy',
                                       'email': '*****@*****.**',
                                       'send_to': '',
                                       'last_name': '',
                                       'token': conf.TOKEN,
                                       'redirect': 'http://www.example.com'})
        env = builder.get_environ()
        req = Request(env)

        # Construct message for assertion
        msg = handler.create_msg(req)
        msg_send = MIMEText(str(msg))
        msg_subj = handler.set_mail_subject(msg)
        msg_send['Subject'] = msg_subj
        msg_send['To'] = conf.EMAIL['default']

        # Mock sendmail function
        smtplib.SMTP.sendmail = Mock('smtplib.SMTP.sendmail')

        # Call send_email and assert sendmail was correctly called
        handler.send_email(msg, msg_subj, send_to_email='default')
        smtplib.SMTP.sendmail.assert_called_with(conf.FROM,
                                                 conf.EMAIL['default'],
                                                 msg_send.as_string())
예제 #22
0
    def test_loading_file(self):
        """Test that it loads image from disk."""
        self.hass.wsgi = mock.MagicMock()

        with NamedTemporaryFile() as fp:
            fp.write('hello'.encode('utf-8'))
            fp.flush()

            assert setup_component(self.hass, 'camera', {
                'camera': {
                    'name': 'config_test',
                    'platform': 'local_file',
                    'file_path': fp.name,
                }})

            image_view = self.hass.wsgi.mock_calls[0][1][0]

            builder = EnvironBuilder(method='GET')
            Request = request_class()
            request = Request(builder.get_environ())
            request.authenticated = True
            resp = image_view.get(request, 'camera.config_test')

            assert resp.status_code == 200, resp.response
            assert resp.response[0].decode('utf-8') == 'hello'
예제 #23
0
    def test_send_email(self):
        """
        Tests send_email

        send_email returns True when it successfully sends an email to a
        default address and errors out when unsuccessful.
        """
        # Build test environment
        builder = EnvironBuilder(method='POST',
                                 data={'name': 'Valid Guy',
                                       'email': '*****@*****.**',
                                       'last_name': '',
                                       'token': conf.TOKEN,
                                       'redirect': 'http://www.example.com'})
        env = builder.get_environ()
        req = Request(env)

        # Construct message for assertion
        msg = handler.create_msg(req)
        msg_send = MIMEText(str(msg))
        msg_subj = handler.set_mail_subject(msg)
        msg_send['Subject'] = msg_subj
        msg_send['To'] = conf.EMAIL['default']

        # Mock sendmail function so it doesn't send an actual email
        smtplib.SMTP.sendmail = Mock('smtplib.SMTP.sendmail')

        # Call send_email and assert sendmail was called correctly
        handler.create_app()
        handler.send_email(msg, msg_subj)
        smtplib.SMTP.sendmail.assert_called_with(conf.FROM,
                                                 conf.EMAIL['default'],
                                                 msg_send.as_string())
예제 #24
0
 def test_format_message(self):
     # Build test environment
     builder = EnvironBuilder(method='POST',
                              data={'name': 'Valid Guy',
                                    'email': '*****@*****.**',
                                    'some_field': ("This is multi line and "
                                                   "should not be on the "
                                                   "same line as the title"),
                                    'redirect': 'http://www.example.com',
                                    'last_name': '',
                                    'token': conf.TOKEN})
     env = builder.get_environ()
     req = Request(env)
     target_message = ("Contact:\n"
                       "--------\n"
                       "NAME:   Valid Guy\n"
                       "EMAIL:   [email protected]\n\n"
                       "Information:\n"
                       "------------\n"
                       "Some Field:\n\n"
                       "This is multi line and should not be on the same "
                       "line as the title\n\n")
     message = handler.create_msg(req)
     formatted_message = handler.format_message(message)
     self.assertEqual(formatted_message, target_message)
예제 #25
0
    def test_redirect_url_error_3(self, mock_validate_email):
        """
        Tests the user is redirected to appropriate location
        """

        # Build test environment
        builder = EnvironBuilder(method='POST',
                                 data={'name': 'Valid Guy',
                                       'email': '*****@*****.**',
                                       'redirect': 'http://www.example.com',
                                       'last_name': '!',
                                       'token': 'wrong token'})
        env = builder.get_environ()
        req = Request(env)

        # Mock validate email so returns true in Travis
        mock_validate_email.return_value = True

        # Create app and mock redirect
        app = handler.create_app()
        werkzeug.utils.redirect = Mock('werkzeug.utils.redirect')
        # Mock sendmail function so it doesn't send an actual email
        smtplib.SMTP.sendmail = Mock('smtplib.SMTP.sendmail')
        app.on_form_page(req)

        werkzeug.utils.redirect.assert_called_with(
            'http://www.example.com?error=3&message=Improper+Form+Submission',
            code=302)
예제 #26
0
    def test_redirect_url_error_4(self, mock_validate_email):
        """
        Tests the user is redirected to appropriate location
        """

        # Build test environment
        builder = EnvironBuilder(method='POST',
                                 data={'name': 'Valid Guy',
                                       'email': '*****@*****.**',
                                       'redirect': 'http://www.example.com',
                                       'last_name': '',
                                       'token': conf.TOKEN})
        env = builder.get_environ()
        req = Request(env)

        # Mock validate email so returns true in Travis
        mock_validate_email.return_value = True
        app = handler.create_app()
        werkzeug.utils.redirect = Mock('werkzeug.utils.redirect')
        # Mock sendmail function so it doesn't send an actual email
        smtplib.SMTP.sendmail = Mock('smtplib.SMTP.sendmail')
        for i in range(conf.CEILING + 1):
            app.on_form_page(req)
            # Avoid duplicate form error
            builder.form['name'] = str(i) + builder.form['name']

        werkzeug.utils.redirect.assert_called_with(
            'http://www.example.com?error=4&message=Too+Many+Requests',
            code=302)
예제 #27
0
    def test_loading_file(self):
        """Test that it loads image from disk."""
        test_string = 'hello'
        self.hass.wsgi = mock.MagicMock()

        with mock.patch('os.path.isfile', mock.Mock(return_value=True)), \
                mock.patch('os.access', mock.Mock(return_value=True)):
            assert setup_component(self.hass, 'camera', {
                'camera': {
                    'name': 'config_test',
                    'platform': 'local_file',
                    'file_path': 'mock.file',
                }})

        image_view = self.hass.wsgi.mock_calls[0][1][0]

        m_open = mock.mock_open(read_data=test_string)
        with mock.patch(
                'homeassistant.components.camera.local_file.open',
                m_open, create=True
        ):
            builder = EnvironBuilder(method='GET')
            Request = request_class()  # pylint: disable=invalid-name
            request = Request(builder.get_environ())
            request.authenticated = True
            resp = image_view.get(request, 'camera.config_test')

        assert resp.status_code == 200, resp.response
        assert resp.response[0].decode('utf-8') == test_string
예제 #28
0
 def setUp(self):
     self.ctx = app.test_request_context()
     self.ctx.push()
     init_data()
     self.client = app.test_client()
     builder = EnvironBuilder(method='POST')
     self.post_env = builder.get_environ()
예제 #29
0
    def test_unregistering_device_view_handles_unknown_subscription(self):
        """Test that the HTML unregister view handles unknown subscriptions."""
        hass = MagicMock()

        config = {
            'some device': SUBSCRIPTION_1,
            'other device': SUBSCRIPTION_2,
        }

        with tempfile.NamedTemporaryFile() as fp:
            hass.config.path.return_value = fp.name
            fp.write(json.dumps(config).encode('utf-8'))
            fp.flush()
            service = html5.get_service(hass, {})

            assert service is not None

            # assert hass.called
            assert len(hass.mock_calls) == 3

            view = hass.mock_calls[1][1][0]
            assert view.json_path == fp.name
            assert view.registrations == config

            builder = EnvironBuilder(method='DELETE', data=json.dumps({
                'subscription': SUBSCRIPTION_3['subscription']
            }))
            Request = request_class()
            resp = view.delete(Request(builder.get_environ()))

            assert resp.status_code == 200, resp.response
            assert view.registrations == config
            with open(fp.name) as fpp:
                assert json.load(fpp) == config
예제 #30
0
 def handler(self, func, param):
     builder = EnvironBuilder(
         method=param['method'],
         path=param['path'],
         query_string=param.get('query_string'),
         headers=param['header'],
         data=base64.b64decode(param['body'])
     )
     environ = builder.get_environ()
     request = Request(environ, populate_request=False, shallow=False)
     response = func(request)
     status = 200
     if isinstance(response, BaseResponse):
         headers = {}
         for k, v in response.headers:
             headers[k] = [v]
         body_byte = response.get_data()
         body = base64.b64encode(body_byte).decode('utf-8')
         status = response.status_code
     elif isinstance(response, str):
         headers = {'Content-Type': ['text/plain; charset=utf-8']}
         body = base64.b64encode(
             bytes(response, 'utf-8')
         ).decode('utf-8')
     else:
         headers = {
             'Content-Type': ['application/json']
          }
         body = encode_base64_json(response).decode('utf-8')
     return {
         'status': status,
         'header': headers,
         'body': body
     }
 def test_wrong_token_jwt_no_sso(self):
     Config.jwt_secret = "jwt_token"
     builder = EnvironBuilder()
     request = Request(builder.get_environ())
     with self.assertRaises(Forbidden):
         self.valid_token(token="lallabalalla", _request=request)
예제 #32
0
    def test_05_api_endpoint_with_multiple_tokens(self):
        # We test the behavior of the TiQR token with other CR tokens (ie. an email token) present
        smtpmock.setdata(response={"*****@*****.**": (200, 'OK')})
        other_token = init_token(
            {
                "type": "email",
                "email": "*****@*****.**",
                "pin": "somepin"
            }, User('selfservice', self.realm1))
        pin = "tiqr"
        token = init_token({
            "type": "tiqr",
            "pin": pin
        }, User('selfservice', self.realm1))
        idetail = token.get_init_detail()
        value = idetail.get("tiqrenroll").get("value")
        # 'tiqrenroll://None?action=metadata&session=b81ecdf74118dcf6fa1cd41d3d4b2fec56c9107f&serial=TiQR000163CB
        # get the serial and the session
        m = re.search('&serial=(.*)$', value)
        serial = m.group(1)
        m = re.search('&session=(.*)&', value)
        session = m.group(1)

        # test meta data
        builder = EnvironBuilder(method='POST', data={}, headers={})
        env = builder.get_environ()
        # Set the remote address so that we can filter for it
        env["REMOTE_ADDR"] = "10.0.0.1"
        g.client_ip = env["REMOTE_ADDR"]
        req = Request(env)
        req.all_data = {
            "action": "metadata",
            "session": session,
            "serial": serial
        }

        r = TiqrTokenClass.api_endpoint(req, g)

        self.assertEqual(r[0], "json")
        self.assertTrue("identity" in r[1], r[1])
        self.assertTrue("service" in r[1], r[1])

        # Test invalid action
        req.all_data = {"action": "unknown"}
        self.assertRaises(Exception, TiqrTokenClass.api_endpoint, req, g)

        # test enrollment with invalid session
        req.all_data = {
            "action": "enrollment",
            "serial": serial,
            "session": "123",
            "secret": KEY20
        }

        self.assertRaises(ParameterError, TiqrTokenClass.api_endpoint, req, g)

        # test enrollment with valid session
        req.all_data = {
            "action": "enrollment",
            "serial": serial,
            "session": session,
            "secret": KEY20
        }
        r = TiqrTokenClass.api_endpoint(req, g)
        self.assertEqual(r[0], "plain")
        self.assertEqual(r[1], "OK")

        # test authentication endpoint
        # create a challenge by issuing validate/triggerchallenge
        with self.app.test_request_context('/validate/triggerchallenge',
                                           method='POST',
                                           data={
                                               "user": "******",
                                               "realm": self.realm1
                                           },
                                           headers={"Authorization": self.at}):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
            result = res.json.get("result")
            detail = res.json.get("detail")
            self.assertTrue(result.get("status") is True, result)
            transaction_id = detail.get("transaction_id")
            # we've got two challenges with the same transaction ID
            self.assertEqual(len(detail["multi_challenge"]), 2)
            email_challenge = [
                challenge for challenge in detail["multi_challenge"]
                if challenge["type"] == "email"
            ][0]
            self.assertEqual(email_challenge["transaction_id"], transaction_id)
            tiqr_challenge = [
                challenge for challenge in detail["multi_challenge"]
                if challenge["type"] == "tiqr"
            ][0]
            self.assertEqual(tiqr_challenge["transaction_id"], transaction_id)
            image_url = tiqr_challenge.get("attributes").get("value")
            self.assertTrue(image_url.startswith("tiqrauth"))
            # u'tiqrauth://[email protected]
            # /12335970131032896263/e0fac7bb2e3ea4219ead'
            # session = 12335970131032896263
            # challenge = e0fac7bb2e3ea4219ead
            r = image_url.split("/")
            session = r[3]
            challenge = r[4]

        # check the URL
        parsed_url = urlparse(image_url)
        self.assertEqual(parsed_url.netloc,
                         "*****@*****.**")

        ocrasuite = token.get_tokeninfo("ocrasuite")
        ocra_object = OCRA(ocrasuite, key=binascii.unhexlify(KEY20))
        # Calculate Response with the challenge.
        response = ocra_object.get_response(challenge)

        encoded_user_id = u"{!s}_{!s}".format("selfservice",
                                              self.realm1).encode('utf-8')
        # First, send a wrong response
        req.all_data = {
            "response": "12345",
            "userId": encoded_user_id,
            "sessionKey": session,
            "operation": "login"
        }
        r = TiqrTokenClass.api_endpoint(req, g)
        self.assertEqual(r[0], "plain")
        self.assertRegexpMatches(r[1], r"INVALID_RESPONSE:[0-9]+")

        # Check that the OTP status is still incorrect
        r = token.check_challenge_response(
            options={"transaction_id": transaction_id})
        self.assertEqual(r, -1)

        # Send the correct response
        req.all_data = {
            "response": response,
            "userId": encoded_user_id,
            "sessionKey": session,
            "operation": "login"
        }
        r = TiqrTokenClass.api_endpoint(req, g)
        self.assertEqual(r[0], "plain")
        self.assertEqual(r[1], "OK")

        # Send the same response a second time would not work
        # since the Challenge is marked as answered
        req.all_data = {
            "response": response,
            "userId": encoded_user_id,
            "sessionKey": session,
            "operation": "login"
        }
        r = TiqrTokenClass.api_endpoint(req, g)
        self.assertEqual(r[0], "plain")
        self.assertEqual(r[1], "INVALID_CHALLENGE")

        # Finally we check the OTP status:
        r = token.check_challenge_response(
            options={"transaction_id": transaction_id})
        self.assertTrue(r > 0, r)

        # Check the same challenge again. It will fail, since the
        # challenge was deleted from the database
        r = token.check_challenge_response(
            options={"transaction_id": transaction_id})
        self.assertTrue(r < 0, r)
예제 #33
0
def set_request(**kwargs):
    builder = EnvironBuilder(**kwargs)
    frappe.local.request = Request(builder.get_environ())
예제 #34
0
def test_iri_support():
    b = EnvironBuilder(u"/föö-bar", base_url=u"http://☃.net/")
    strict_eq(b.path, "/f%C3%B6%C3%B6-bar")
    strict_eq(b.base_url, "http://xn--n3h.net/")
예제 #35
0
 def test_iri_support(self):
     b = EnvironBuilder(u'/föö-bar', base_url=u'http://☃.net/')
     self.assert_strict_equal(b.path, '/f%C3%B6%C3%B6-bar')
     self.assert_strict_equal(b.base_url, 'http://xn--n3h.net/')
예제 #36
0
    def path(self, uri):
        """Returns the physical path that the provided URI respolves
        to. Returns None if this requesthandler does not support the
        given URI, or the URI doesnt resolve to a static file.
        
        """
        suffix = None
        parsedurl = urlparse(uri)
        args = dict(parse_qsl(parsedurl.query))
        map = Map(self.rules, converters=self.rule_converters)
        endpoint, params = map.bind(server_name=parsedurl.netloc.split(":")[0],
                                    path_info=parsedurl.path).match()
        if endpoint == self.handle_dataset:
            # FIXME: This duplicates logic from handle_dataset
            assert len(
                args
            ) <= 1, "Can't handle dataset requests with multiple selectors"
            for (k, v) in args.items():
                params["param"] = k
                params["value"] = v
            # at this point, use werkzeug.test.Client or
            # EnvironmentBuilder to create a fake environ and then a
            # fake Request object
            if ".atom" in uri:
                suffix = "atom"
                path = "/index.atom"
                headers = {}
            else:
                headers = {"Accept": "text/html"}
                path = "/index.html"
            environ = EnvironBuilder(path=path, headers=headers).get_environ()
            contenttype = self.contenttype(Request(environ), suffix)
            pathfunc = self.get_dataset_pathfunc(environ, params, contenttype,
                                                 suffix)
            if pathfunc:
                return pathfunc()
            else:
                return None
        elif endpoint == self.handle_doc:
            # params = self.params_from_uri(uri)
            # if params:
            params.update(args)

            if 'basefile' not in params:
                return None
            if 'format' in params:
                suffix = params['format']
            else:
                if 'attachment' in params:
                    leaf = params['attachment']
                else:
                    leaf = uri.split("/")[-1]
                if "." in leaf:
                    suffix = leaf.rsplit(".", 1)[1]

        if not suffix:
            headers = {'Accept': 'text/html'}
        else:
            headers = {}
        environ = EnvironBuilder(path=urlparse(uri).path,
                                 headers=headers).get_environ()
        contenttype = self.contenttype(Request(environ), suffix)
        pathfunc = self.get_pathfunc(environ, params['basefile'], params,
                                     contenttype, suffix)
        if pathfunc:
            return pathfunc(params['basefile'])
예제 #37
0
 def test_form_type(self):
     """Try a normal form-urlencoded request."""
     builder = EnvironBuilder(method='POST', data={'foo': 'bar'})
     request = Request(builder.get_environ())
     data = decode_request(request)
     assert data['foo'] == 'bar'
예제 #38
0
    def _test_api_endpoint(self, user, expected_netloc):
        pin = "tiqr"
        token = init_token({
            "type": "tiqr",
            "pin": pin
        }, User(user, self.realm1))
        idetail = token.get_init_detail()
        value = idetail.get("tiqrenroll").get("value")
        # 'tiqrenroll://None?action=metadata&session=b81ecdf74118dcf6fa1cd41d3d4b2fec56c9107f&serial=TiQR000163CB
        # get the serial and the session
        m = re.search('&serial=(.*)$', value)
        serial = m.group(1)
        m = re.search('&session=(.*)&', value)
        session = m.group(1)

        # test meta data
        builder = EnvironBuilder(method='POST', data={}, headers={})
        env = builder.get_environ()
        # Set the remote address so that we can filter for it
        env["REMOTE_ADDR"] = "10.0.0.1"
        g.client_ip = env["REMOTE_ADDR"]
        req = Request(env)
        req.all_data = {
            "action": "metadata",
            "session": session,
            "serial": serial
        }

        r = TiqrTokenClass.api_endpoint(req, g)

        self.assertEqual(r[0], "json")
        self.assertTrue("identity" in r[1], r[1])
        self.assertTrue("service" in r[1], r[1])

        # Test invalid action
        req.all_data = {"action": "unknown"}
        self.assertRaises(Exception, TiqrTokenClass.api_endpoint, req, g)

        # test enrollment with invalid session
        req.all_data = {
            "action": "enrollment",
            "serial": serial,
            "session": "123",
            "secret": KEY20
        }

        self.assertRaises(ParameterError, TiqrTokenClass.api_endpoint, req, g)

        # test enrollment with valid session
        req.all_data = {
            "action": "enrollment",
            "serial": serial,
            "session": session,
            "secret": KEY20
        }
        r = TiqrTokenClass.api_endpoint(req, g)
        self.assertEqual(r[0], "plain")
        self.assertEqual(r[1], "OK")

        # test authentication endpoint
        # create a challenge by issuing validate/check with user and pin
        session = ""
        challenge = ""
        with self.app.test_request_context('/validate/check',
                                           method='GET',
                                           query_string=urlencode({
                                               "user":
                                               user.encode('utf-8'),
                                               "realm":
                                               self.realm1,
                                               "pass":
                                               pin
                                           })):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
            result = res.json.get("result")
            detail = res.json.get("detail")
            self.assertTrue(result.get("status") is True, result)
            self.assertTrue(result.get("value") is False, result)
            transaction_id = detail.get("transaction_id")
            image_url = detail.get("attributes").get("value")
            self.assertTrue(image_url.startswith("tiqrauth"))
            # u'tiqrauth://[email protected]
            # /12335970131032896263/e0fac7bb2e3ea4219ead'
            # session = 12335970131032896263
            # challenge = e0fac7bb2e3ea4219ead
            r = image_url.split("/")
            session = r[3]
            challenge = r[4]

        # check the URL
        parsed_url = urlparse(image_url)
        self.assertEqual(parsed_url.netloc, expected_netloc)

        ocrasuite = token.get_tokeninfo("ocrasuite")
        ocra_object = OCRA(ocrasuite, key=binascii.unhexlify(KEY20))
        # Calculate Response with the challenge.
        response = ocra_object.get_response(challenge)

        encoded_user_id = u"{!s}_{!s}".format(user,
                                              self.realm1).encode('utf-8')
        # First, send a wrong response
        req.all_data = {
            "response": "12345",
            "userId": encoded_user_id,
            "sessionKey": session,
            "operation": "login"
        }
        r = TiqrTokenClass.api_endpoint(req, g)
        self.assertEqual(r[0], "plain")
        # check the failed response count
        fcnt1 = token.get_max_failcount() - token.get_failcount()
        self.assertRegexpMatches(r[1], r"INVALID_RESPONSE:{0!s}".format(fcnt1))

        # Try another wrong response
        req.all_data = {
            "response": "67890",
            "userId": encoded_user_id,
            "sessionKey": session,
            "operation": "login"
        }
        r = TiqrTokenClass.api_endpoint(req, g)
        self.assertEqual(r[0], "plain")
        # check the failed response count
        fcnt2 = token.get_max_failcount() - token.get_failcount()
        self.assertRegexpMatches(r[1], r"INVALID_RESPONSE:{0!s}".format(fcnt2))
        # has the failcounter decreased?
        self.assertEqual(fcnt1 - 1, fcnt2)

        # Check that the OTP status is still incorrect
        r = token.check_challenge_response(
            options={"transaction_id": transaction_id})
        self.assertEqual(r, -1)

        # Send the correct response
        req.all_data = {
            "response": response,
            "userId": encoded_user_id,
            "sessionKey": session,
            "operation": "login"
        }
        r = TiqrTokenClass.api_endpoint(req, g)
        self.assertEqual(r[0], "plain")
        self.assertEqual(r[1], "OK")

        # Send the same response a second time would not work
        # since the Challenge is marked as answered
        req.all_data = {
            "response": response,
            "userId": encoded_user_id,
            "sessionKey": session,
            "operation": "login"
        }
        r = TiqrTokenClass.api_endpoint(req, g)
        self.assertEqual(r[0], "plain")
        self.assertEqual(r[1], "INVALID_CHALLENGE")

        # Finally we check the OTP status:
        r = token.check_challenge_response(
            options={"transaction_id": transaction_id})
        self.assertTrue(r > 0, r)

        # Check the same challenge again. It will fail, since the
        # challenge was deleted from the database
        r = token.check_challenge_response(
            options={"transaction_id": transaction_id})
        self.assertTrue(r < 0, r)
 def test_wsgi_app_404(self):
     Logger.set_log_level("ERROR")
     res = self.server.wsgi_app(
         EnvironBuilder('/not_found').get_environ(), None)
     self.assertIsInstance(res, NotFound)
예제 #40
0
def _get_werkzeug_request(path):
    builder = EnvironBuilder(path=path)
    env = builder.get_environ()
    return Request(env)
예제 #41
0
 def test_iri_support(self):
     b = EnvironBuilder(u'/föö-bar', base_url=u'http://☃.net/')
     assert b.path == '/f%C3%B6%C3%B6-bar'
     assert b.base_url == 'http://xn--n3h.net/'
예제 #42
0
def set_request(**kwargs):
    from werkzeug.test import EnvironBuilder
    from werkzeug.wrappers import Request
    builder = EnvironBuilder(**kwargs)
    frappe.local.request = Request(builder.get_environ())
예제 #43
0
def test_iri_support():
    b = EnvironBuilder("/föö-bar", base_url="http://☃.net/")
    assert b.path == "/f%C3%B6%C3%B6-bar"
    assert b.base_url == "http://xn--n3h.net/"
    def test_wsgi_app(self):
        res = self.server.wsgi_app(
            EnvironBuilder('/contest').get_environ(), None)
        data = json.loads(res.data.decode())

        self.assertFalse(data["has_started"])
예제 #45
0
import io
import pathlib

import pytest

from werkzeug.exceptions import NotFound
from werkzeug.http import http_date
from werkzeug.test import EnvironBuilder
from werkzeug.utils import send_file
from werkzeug.utils import send_from_directory

res_path = pathlib.Path(__file__).parent / "res"
html_path = res_path / "index.html"
txt_path = res_path / "test.txt"

environ = EnvironBuilder().get_environ()


@pytest.mark.parametrize("path", [html_path, str(html_path)])
def test_path(path):
    rv = send_file(path, environ)
    assert rv.mimetype == "text/html"
    assert rv.direct_passthrough
    rv.direct_passthrough = False
    assert rv.data == html_path.read_bytes()
    rv.close()


def test_x_sendfile():
    rv = send_file(html_path, environ, use_x_sendfile=True)
    assert rv.headers["x-sendfile"] == str(html_path)
예제 #46
0
def make_test_environ_builder(app,
                              path='/',
                              base_url=None,
                              subdomain=None,
                              url_scheme=None,
                              *args,
                              **kwargs):
    """Create a :class:`~werkzeug.test.EnvironBuilder`, taking some
    defaults from the application.

    :param app: The Flask application to configure the environment from.
    :param path: URL path being requested.
    :param base_url: Base URL where the utils is being served, which
        ``path`` is relative to. If not given, built from
        :data:`PREFERRED_URL_SCHEME`, ``subdomain``,
        :data:`SERVER_NAME`, and :data:`APPLICATION_ROOT`.
    :param subdomain: Subdomain name to append to :data:`SERVER_NAME`.
    :param url_scheme: Scheme to use instead of
        :data:`PREFERRED_URL_SCHEME`.
    :param json: If given, this is serialized as JSON and passed as
        ``data``. Also defaults ``content_type`` to
        ``application/json``.
    :param args: other positional arguments passed to
        :class:`~werkzeug.test.EnvironBuilder`.
    :param kwargs: other keyword arguments passed to
        :class:`~werkzeug.test.EnvironBuilder`.
    """

    assert (not (base_url or subdomain or url_scheme)
            or (base_url is not None) != bool(subdomain or url_scheme)
            ), 'Cannot pass "subdomain" or "url_scheme" with "base_url".'

    if base_url is None:
        http_host = app.config.get('SERVER_NAME') or 'localhost'
        app_root = app.config['APPLICATION_ROOT']

        if subdomain:
            http_host = '{0}.{1}'.format(subdomain, http_host)

        if url_scheme is None:
            url_scheme = app.config['PREFERRED_URL_SCHEME']

        url = url_parse(path)
        base_url = '{scheme}://{netloc}/{path}'.format(
            scheme=url.scheme or url_scheme,
            netloc=url.netloc or http_host,
            path=app_root.lstrip('/'))
        path = url.path

        if url.query:
            sep = b'?' if isinstance(url.query, bytes) else '?'
            path += sep + url.query

    if 'json' in kwargs:
        assert 'data' not in kwargs, (
            "Client cannot provide both 'json' and 'data'.")

        # push a context so flask.json can use utils's json attributes
        with app.app_context():
            kwargs['data'] = json_dumps(kwargs.pop('json'))

        if 'content_type' not in kwargs:
            kwargs['content_type'] = 'application/json'

    return EnvironBuilder(path, base_url, *args, **kwargs)
예제 #47
0
def test_auth_object():
    builder = EnvironBuilder(
        auth=Authorization("digest", {"username": "******", "password": "******"})
    )
    request = builder.get_request()
    assert request.headers["Authorization"].startswith("Digest ")
예제 #48
0
def test_basic_auth():
    builder = EnvironBuilder(auth=("username", "password"))
    request = builder.get_request()
    auth = parse_authorization_header(request.headers["Authorization"])
    assert auth.username == "username"
    assert auth.password == "password"
예제 #49
0
def test_iri_support():
    """Test client IRI support"""
    b = EnvironBuilder(u'/föö-bar', base_url=u'http://☃.net/')
    assert b.path == '/f%C3%B6%C3%B6-bar'
    assert b.base_url == 'http://xn--n3h.net/'
예제 #50
0
class WSGI(RepoTester): # base class w/o tests
    storetype = 'SQLITE'
    storelocation = 'data/ferenda.sqlite' # append self.datadir
    storerepository = 'ferenda'
    indextype = 'WHOOSH'
    indexlocation = 'data/whooshindex' # append self.datadir
    def setUp(self):
        super(WSGI,self).setUp()
        if self.storelocation.startswith("data/"):
            self.storelocation = self.storelocation.replace("data", self.datadir)
        if self.indexlocation.startswith("data/"):
            self.indexlocation = self.indexlocation.replace("data", self.datadir)
        self.put_files_in_place()
        # use self.repo (simple testcases) or self.repos (complex
        # testcases like AdvancedAPI)?
        if hasattr(self, 'repos'):
            repos = self.repos
        else:
            repos = [self.repo]
            
        # print("making app: %s %s" % (self.storetype, self.indextype))
        config = LayeredConfig(Defaults({'datadir': self.datadir,
                                         'apiendpoint': '/myapi/',
                                         'searchendpoint': '/mysearch/',
                                         'url': 'http://localhost:8000/',
                                         'storetype': self.storetype,
                                         'storelocation': self.storelocation,
                                         'storerepository': self.storerepository,
                                         'indextype': self.indextype,
                                         'indexlocation': self.indexlocation,
                                         'wsgiappclass': 'ferenda.WSGIApp',
                                         'legacyapi': False,
                                         'wsgiexceptionhandler': True}))
        self.app = manager.make_wsgi_app(config, repos=repos)
        self.builder = EnvironBuilder('/', base_url="http://localhost:8000/",
                                      headers={"Accept": DEFAULT_HTTP_ACCEPT})

    def ttl_to_rdf_xml(self, inpath, outpath, store=None):
        if not store:
            store = self.repo.store
        g = Graph()
        g.parse(data=util.readfile(inpath, encoding="utf-8"), format="turtle")
        with _open(outpath, "wb") as fp:
            fp.write(g.serialize(format="pretty-xml"))
        return g

    def put_files_in_place(self):
        # Put files in place: parsed
        util.ensure_dir(self.repo.store.parsed_path("123/a"))
        shutil.copy2("test/files/base/parsed/123/a.xhtml",
                     self.repo.store.parsed_path("123/a"))
        g = self.ttl_to_rdf_xml("test/files/base/distilled/123/a.ttl",
                                self.repo.store.distilled_path("123/a"))

        # generated
        util.ensure_dir(self.repo.store.generated_path("123/a"))
        shutil.copy2("test/files/base/generated/123/a.html",
                     self.repo.store.generated_path("123/a"))
        shutil.copy2("test/files/base/generated/123/a.html",
                     self.repo.store.generated_path("123/a"))

        # annotations
        util.ensure_dir(self.repo.store.annotation_path("123/a"))
        shutil.copy2("test/files/base/annotations/123/a.grit.xml",
                     self.repo.store.annotation_path("123/a"))

        # config
        resources = self.datadir+os.sep+"rsrc"+os.sep+"resources.xml"
        util.ensure_dir(resources)
        shutil.copy2("test/files/base/rsrc/resources.xml",
                     resources)

        # index.html
        index = self.datadir+os.sep+"index.html"
        with open(index, "wb") as fp:
            fp.write(b'<h1>index.html</h1>')

        # toc/index.html + toc/title/a.html
        with self.repo.store.open("index", "toc", ".html", "wb") as fp:
            fp.write(b'<h1>TOC for base</h1>')
        with self.repo.store.open("title/a", "toc", ".html", "wb") as fp:
            fp.write(b'<h1>Title starting with "a"</h1>')

        # distilled/dump.nt
        with self.repo.store.open("dump", "distilled", ".nt", "wb") as fp:
            fp.write(g.serialize(format="nt"))

    def call_wsgi(self, environ=None):
        if not environ:
            environ = self.builder.get_environ()
        start_response = Mock()
        buf = BytesIO()
        iterable = self.app(environ, start_response)
        for chunk in iterable:
            buf.write(chunk)
        if hasattr(iterable, 'close'):
            iterable.close()
        call_args = start_response.mock_calls[0][1]
        # call_kwargs = start_response.mock_calls[0][2]
        return call_args[0], call_args[1], buf.getvalue()

    def assertResponse(self,
                       wanted_status,
                       wanted_headers,
                       wanted_content,
                       got_status,
                       got_headers,
                       got_content):
        self.assertEqual(wanted_status, got_status)
        got_headers = dict(got_headers)
        for (key, value) in wanted_headers.items():
            self.assertEqual(value, got_headers[key])
        if wanted_content:
            self.assertEqual(wanted_content, got_content)
예제 #51
0
def get_request(obj):
    builder = EnvironBuilder("/", data=encode.dumper(obj))
    builder.headers["content-type"] = "application/json"
    return JsonWebRequest(builder.get_environ())
예제 #52
0
def get_request(*args, **kw):
    return Request(EnvironBuilder(*args, **kw).get_environ())
예제 #53
0
def make_test_environ_builder(app,
                              path="/",
                              base_url=None,
                              subdomain=None,
                              url_scheme=None,
                              *args,
                              **kwargs):
    """Create a :class:`~werkzeug.test.EnvironBuilder`, taking some
    defaults from the application.

    :param app: The Flask application to configure the environment from.
    :param path: URL path being requested.
    :param base_url: Base URL where the app is being served, which
        ``path`` is relative to. If not given, built from
        :data:`PREFERRED_URL_SCHEME`, ``subdomain``,
        :data:`SERVER_NAME`, and :data:`APPLICATION_ROOT`.
    :param subdomain: Subdomain name to append to :data:`SERVER_NAME`.
    :param url_scheme: Scheme to use instead of
        :data:`PREFERRED_URL_SCHEME`.
    :param json: If given, this is serialized as JSON and passed as
        ``data``. Also defaults ``content_type`` to
        ``application/json``.
    :param args: other positional arguments passed to
        :class:`~werkzeug.test.EnvironBuilder`.
    :param kwargs: other keyword arguments passed to
        :class:`~werkzeug.test.EnvironBuilder`.
    """

    assert not (base_url or subdomain
                or url_scheme) or (base_url is not None) != bool(
                    subdomain or url_scheme
                ), 'Cannot pass "subdomain" or "url_scheme" with "base_url".'

    if base_url is None:
        http_host = app.config.get("SERVER_NAME") or "localhost"
        app_root = app.config["APPLICATION_ROOT"]

        if subdomain:
            http_host = "{0}.{1}".format(subdomain, http_host)

        if url_scheme is None:
            url_scheme = app.config["PREFERRED_URL_SCHEME"]

        url = url_parse(path)
        base_url = "{scheme}://{netloc}/{path}".format(
            scheme=url.scheme or url_scheme,
            netloc=url.netloc or http_host,
            path=app_root.lstrip("/"),
        )
        path = url.path

        if url.query:
            sep = b"?" if isinstance(url.query, bytes) else "?"
            path += sep + url.query

    # TODO use EnvironBuilder.json_dumps once we require Werkzeug 0.15
    if "json" in kwargs:
        assert "data" not in kwargs, "Client cannot provide both 'json' and 'data'."
        kwargs["data"] = json_dumps(kwargs.pop("json"), app=app)

        if "content_type" not in kwargs:
            kwargs["content_type"] = "application/json"

    return EnvironBuilder(path, base_url, *args, **kwargs)
예제 #54
0
class TestFileByDigestMiddleware(unittest.TestCase):
    def setUp(self):
        # Choose a size that is larger than FileCacher.CHUNK_SIZE.
        self.content = \
            bytes(random.getrandbits(8) for _ in range(17 * 1024))
        self.digest = bytes_digest(self.content)

        self.filename = "foobar.pdf"
        self.mimetype = "image/jpeg"

        self.file_cacher = Mock()
        self.file_cacher.get_file = Mock(
            side_effect=lambda digest: io.BytesIO(self.content))
        self.file_cacher.get_size = Mock(return_value=len(self.content))

        self.serve_file = True
        self.provide_filename = True

        self.wsgi_app = \
            FileServerMiddleware(self.file_cacher,self.wrapped_wsgi_app)
        self.environ_builder = EnvironBuilder("/some/url")
        self.client = Client(self.wsgi_app, Response)

    @responder
    def wrapped_wsgi_app(self, environ, start_response):
        self.assertEqual(environ, self.environ)
        if self.serve_file:
            headers = {FileServerMiddleware.DIGEST_HEADER: self.digest}
            if self.provide_filename:
                headers[FileServerMiddleware.FILENAME_HEADER] = self.filename
            return Response(headers=headers, mimetype=self.mimetype)
        else:
            return Response(b"some other content", mimetype="text/plain")

    def request(self, headers=None):
        if headers is not None:
            for key, value in headers:
                self.environ_builder.headers.add(key, value)
        self.environ = self.environ_builder.get_environ()
        return self.client.open(self.environ)

    def test_success(self):
        response = self.request()

        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.mimetype, self.mimetype)
        self.assertEqual(
            response.headers.get("content-disposition"),
            "attachment; filename=%s" % quote_header_value(self.filename))
        self.assertTupleEqual(response.get_etag(), (self.digest, False))
        self.assertEqual(response.accept_ranges, "bytes")
        self.assertGreater(response.cache_control.max_age, 0)
        self.assertTrue(response.cache_control.private)
        self.assertFalse(response.cache_control.public)
        self.assertEqual(response.get_data(), self.content)

        self.file_cacher.get_file.assert_called_once_with(self.digest)

    def test_not_a_file(self):
        self.serve_file = False

        response = self.request()

        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.mimetype, "text/plain")
        self.assertEqual(response.get_data(), b"some other content")

    def test_no_filename(self):
        self.provide_filename = False

        response = self.request()

        self.assertNotIn("content-disposition", response.headers)

    def test_not_found(self):
        self.file_cacher.get_file.side_effect = KeyError()

        response = self.request()

        self.assertEqual(response.status_code, 404)
        self.file_cacher.get_file.assert_called_once_with(self.digest)

    def test_tombstone(self):
        self.file_cacher.get_file.side_effect = TombstoneError()

        response = self.request()

        self.assertEqual(response.status_code, 503)
        self.file_cacher.get_file.assert_called_once_with(self.digest)

    def test_conditional_request(self):
        # Test an etag that matches.
        response = self.request(headers=[("If-None-Match", self.digest)])
        self.assertEqual(response.status_code, 304)
        self.assertEqual(len(response.get_data()), 0)

    def test_conditional_request_no_match(self):
        # Test an etag that doesn't match.
        response = self.request(headers=[("If-None-Match", "not the etag")])
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.get_data(), self.content)

    def test_range_request(self):
        # Test a range that is strictly included.
        response = self.request(headers=[("Range", "bytes=256-767")])
        self.assertEqual(response.status_code, 206)
        self.assertEqual(response.content_range.units, "bytes")
        self.assertEqual(response.content_range.start, 256)
        self.assertEqual(response.content_range.stop, 768)
        self.assertEqual(response.content_range.length, 1024)
        self.assertEqual(response.get_data(), self.content[256:768])

    def test_range_request_end_overflows(self):
        # Test a range that ends after the end of the file.
        response = self.request(headers=[("Range", "bytes=256-2047")])
        self.assertEqual(response.status_code, 206)
        self.assertEqual(response.content_range.units, "bytes")
        self.assertEqual(response.content_range.start, 256)
        self.assertEqual(response.content_range.stop, 1024)
        self.assertEqual(response.content_range.length, 1024)
        self.assertEqual(response.get_data(), self.content[256:])

    def test_range_request_start_overflows(self):
        # Test a range that starts after the end of the file.
        response = self.request(headers=[("Range", "bytes=1536-")])
        self.assertEqual(response.status_code, 416)