Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Set up proper live server environment and urllib2 tests

  • Loading branch information...
commit 4d49787ff511ec3a2b2c42ddd62a462bdc182553 1 parent 797c4a5
almad authored
View
6 djangohttpdigest/__init__.py
@@ -1,3 +1,7 @@
__version__ = (0, 1, 0, 'pre')
-__versionstr__ = '0.1.0-pre'
+__versionstr__ = '0.1.0-pre'
+
+from decorators import (
+ protect_digest
+)
View
39 djangohttpdigest/client.py
@@ -9,3 +9,42 @@
class HttpDigestClient(Client):
""" Extend Django's client for HTTP digest support """
+
+ def set_http_authentication(self, username, password, path):
+ self.http_username = username
+ self.http_password = password
+ self.http_path = path
+
+ def http_authenticate(self, response, method, queryargs=None):
+ """
+ Authenticate using HTTP digest and return our second request.
+ If problem occurs and we cannot repeat our request, return original one.
+ """
+ if not response.has_key('WWW-Authenticate'):
+ # server has not send needed authentication information
+ return response
+ (authentication_method, auth) = response['WWW-Authenticate'].split(" ", 1)
+ if authmeth.lower() != 'digest':
+ raise ValueError("Unsupported authentication method %s" % authmeth)
+
+ def get(self, url, data=None, *args, **kwargs):
+ data = data or {}
+ response = Client.get(self, url, data, *args, **kwargs)
+ if response.status_code == 401:
+ return self.http_authenticate(response=response, method='get', queryargs=data)
+
+ def post(self, url, *args, **kwargs):
+ response = Client.post(self, url, *args, **kwargs)
+
+ def put(self, url, *args, **kwargs):
+ response = Client.put(self, url, *args, **kwargs)
+
+ def delete(self, url, *args, **kwargs):
+ response = Client.delete(self, url, *args, **kwargs)
+
+ def options(self, url, *args, **kwargs):
+ response = Client.options(self, url, *args, **kwargs)
+
+ def head(self, url, *args, **kwargs):
+ response = Client.head(self, url, *args, **kwargs)
+
View
8 djangohttpdigest/decorators.py
@@ -0,0 +1,8 @@
+from http import HttpResponseNotAuthorized
+def protect_digest(realm, username, password):
+ def _innerDecorator(f):
+ def _wrapper(*args, **kwargs):
+ return HttpResponseNotAuthorized("Not Authorized")
+ return _wrapper
+ return _innerDecorator
+
View
8 djangohttpdigest/http.py
@@ -0,0 +1,8 @@
+"""
+Fixes around django.http
+"""
+
+from django.http import HttpResponse
+
+class HttpResponseNotAuthorized(HttpResponse):
+ status_code = 401
View
41 djangohttpdigest/tests/test_simple_digest.py
@@ -1,12 +1,43 @@
+import urllib2
+
from django.test import TestCase
+
from djangohttpdigest.client import HttpDigestClient
-class TestSimpleDigest(TestCase):
+from module_test import LiveServerTestCase
+
+class TestSimpleDigest(LiveServerTestCase):
+ path = '/testapi/simpleprotected/'
+ url = 'http://localhost:8000'
- def test_simple_authorization(self):
+ def test_simple_autentization(self):
""" Test view protected by simple realm-username-password decorator """
- path = '/testapi/simpleprotected/'
+
# first test that using normal client, path is protected and returns 401
- response = self.client.get(path)
- self.assertEquals(401, response.status_code)
+ response = self.client.get(self.path)
+ self.assertEquals(401, response.status_code)
+
+ #Now use our client ant autentize
+# client = HttpDigestClient()
+# client.set_http_authentication(username='username', password='password', path=self.path)
+# response = client.get(self.path)
+# self.assertEquals(200, response.status_code)
+
+
+ def test_autentization_compatible(self):
+ """ Check our server-side autentization is compatible with standard (urllib2) one """
+
+ auth_handler = urllib2.HTTPDigestAuthHandler()
+ auth_handler.add_password('localhost', self.url, 'username', 'password')
+ opener = urllib2.build_opener(auth_handler)
+
+ request = urllib2.Request(self.url+self.path)
+ try:
+ response = opener.open(request)
+ except urllib2.HTTPError, err:
+ print err.fp.read()
+ raise
+ self.assertEquals(200, response.code)
+ response.close()
+
View
3  run_tests
@@ -1,4 +1,5 @@
#!/bin/sh
cd testproject
-./manage.py test $1
+#./manage.py test $1
+./livetests.py
exit $?;
View
36 testproject/livetests.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+""" Run webtests """
+
+import sys
+import os, os.path
+
+from django.core.management import setup_environ
+import nose
+from nose.config import Config, all_config_files
+from nose.plugins.manager import DefaultPluginManager
+
+import settings
+setup_environ(settings)
+
+from server_runner import ServerRunner
+
+def run_selenium_tests():
+
+ # nose config
+ config = Config(files=all_config_files(), plugins=DefaultPluginManager())
+ config.workingDir = os.path.join(os.path.dirname(__file__))
+ server_runner = ServerRunner()
+ server_runner.run_server()
+ success = nose.run(config=config)
+ server_runner.stop_server()
+
+ return success
+
+def main():
+ success = run_selenium_tests()
+
+ sys.exit(not success)
+
+if __name__ == '__main__':
+ main()
View
56 testproject/server_runner.py
@@ -0,0 +1,56 @@
+# -*- coding: utf-8 -*-
+__license__ = """
+ Copyright (c) 2007 Mikeal Rogers
+ Modified for RPGPedia project (c) 2008 by Almad
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+"""
+
+
+import sys, os
+from time import sleep
+from threading import Thread
+
+import cherrypy
+
+__all__ = ["ServerRunner"]
+
+class ServerRunner(object):
+
+ def __init__(self, port=8000):
+ self.port = port
+ self.httpd = None
+ self.http_thread = None
+
+ def run_server(self):
+
+ import django.core.handlers.wsgi
+ _application = django.core.handlers.wsgi.WSGIHandler()
+
+ def application(environ, start_response):
+ environ['PATH_INFO'] = environ['SCRIPT_NAME'] + environ['PATH_INFO']
+ return _application(environ, start_response)
+
+ import cherrypy
+ httpd = cherrypy.wsgiserver.CherryPyWSGIServer(('', self.port), application, server_name='django-test-http')
+ httpd_thread = Thread(target=httpd.start)
+ httpd_thread.start()
+ sleep(.5)
+
+ self.httpd_thread = httpd_thread
+ self.httpd = httpd
+
+ def stop_server(self):
+ self.httpd.stop()
View
2  testproject/testapi/views.py
@@ -1,5 +1,7 @@
from django.http import HttpResponse
+from djangohttpdigest import protect_digest
+@protect_digest(realm='simple', username='username', password='password')
def simpleprotected(request):
"""
This is example of far too simply protected value
Please sign in to comment.
Something went wrong with that request. Please try again.