
commit 730ab250aa473645c498d1a17254e494fb6ec115 Author: Damian Johnson <atagar@torproject.org> Date: Sat Dec 20 13:36:54 2014 -0800 Unit test for hidden service tutorial example --- docs/tutorials/over_the_river.rst | 2 +- test/unit/tutorial.py | 73 +++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/docs/tutorials/over_the_river.rst b/docs/tutorials/over_the_river.rst index 968f53d..b7aa8f4 100644 --- a/docs/tutorials/over_the_river.rst +++ b/docs/tutorials/over_the_river.rst @@ -16,7 +16,7 @@ Hidden services can be `configured through your torrc <https://www.torproject.or The main threat to your anonymity when running a hidden service is the service itself. Debug information for instance might leak your real address, undermining what Tor provides. This includes the following example, **do not rely on it not to leak**. -But with that out of the way lets take a look at a simple example based on one by `Jordan Wright <https://jordan-wright.github.io/blog/2014/10/06/creating-tor-hidden-services-with-python/>`_... +But with that out of the way lets take a look at a simple `Flask <http://flask.pocoo.org/>`_ example based on one by `Jordan Wright <https://jordan-wright.github.io/blog/2014/10/06/creating-tor-hidden-services-with-python/>`_... :: diff --git a/test/unit/tutorial.py b/test/unit/tutorial.py index 1ee6396..5a861b6 100644 --- a/test/unit/tutorial.py +++ b/test/unit/tutorial.py @@ -17,6 +17,13 @@ try: except ImportError: from mock import Mock, patch +OVER_THE_RIVER_OUTPUT = """\ + * Connecting to tor + * Creating our hidden service in /home/atagar/.tor/hello_world + * Our service is available at uxiuaxejc3sxrb6i.onion, press ctrl+c to quit + * Shutting down our hidden service +""" + MIRROR_MIRROR_OUTPUT = """\ 1. speedyexit (102.13 KB/s) 2. speedyexit (102.13 KB/s) @@ -49,6 +56,72 @@ class TestTutorial(unittest.TestCase): self.assertEqual('My Tor relay has read 33406 bytes and written 29649.\n', stdout_mock.getvalue()) @patch('sys.stdout', new_callable = StringIO.StringIO) + @patch('shutil.rmtree') + @patch('stem.control.Controller.from_port', spec = Controller) + def test_over_the_river(self, from_port_mock, rmtree_mock, stdout_mock): + def tutorial_example(app): + import os + import shutil + + from stem.control import Controller + + @app.route('/') + def index(): + return "<h1>Hi Grandma!</h1>" + + print ' * Connecting to tor' + + with Controller.from_port() as controller: + controller.authenticate() + + # All hidden services have a directory on disk. Lets put ours in tor's data + # directory. + + hidden_service_dir = os.path.join(controller.get_conf('DataDirectory', '/tmp'), 'hello_world') + + # Create a hidden service where visitors of port 80 get redirected to local + # port 5000 (this is where flask runs by default). + + print " * Creating our hidden service in %s" % hidden_service_dir + result = controller.create_hidden_service(hidden_service_dir, 80, target_port = 5000) + + # The hostname is only available we can read the hidden service directory. + # This requires us to be running with the same user as tor. + + if result.hostname: + print " * Our service is available at %s, press ctrl+c to quit" % result.hostname + else: + print " * Unable to determine our service's hostname, probably due to being unable to read the hidden service directory" + + try: + app.run() + finally: + # Shut down the hidden service and clean it off disk. Note that you *don't* + # want to delete the hidden service directory if you'd like to have this + # same *.onion address in the future. + + print " * Shutting down our hidden service" + controller.remove_hidden_service(hidden_service_dir) + shutil.rmtree(hidden_service_dir) + + flask_mock = Mock() + + hidden_service_data = Mock() + hidden_service_data.hostname = 'uxiuaxejc3sxrb6i.onion' + + controller = from_port_mock().__enter__() + controller.get_conf.return_value = '/home/atagar/.tor' + controller.create_hidden_service.return_value = hidden_service_data + + tutorial_example(flask_mock) + + controller.get_conf.assert_called_once_with('DataDirectory', '/tmp') + controller.create_hidden_service.assert_called_once_with('/home/atagar/.tor/hello_world', 80, target_port = 5000) + rmtree_mock.assert_called_once_with('/home/atagar/.tor/hello_world') + + self.assertEqual(OVER_THE_RIVER_OUTPUT, stdout_mock.getvalue()) + + @patch('sys.stdout', new_callable = StringIO.StringIO) @patch('stem.descriptor.remote.DescriptorDownloader') def test_mirror_mirror_on_the_wall_1(self, downloader_mock, stdout_mock): def tutorial_example():
participants (1)
-
atagar@torproject.org