rename package finish testing

This commit is contained in:
Olivier Larchevêque 2013-08-12 15:13:07 -04:00
parent 6ef2d78904
commit 37a05844fb
31 changed files with 289 additions and 150 deletions

View File

@ -1 +1 @@
recursive-include secretquestions/templates *
recursive-include auf/django/secretquestions/templates *

2
auf/__init__.py Normal file
View File

@ -0,0 +1,2 @@
import pkg_resources
pkg_resources.declare_namespace(__name__)

2
auf/django/__init__.py Normal file
View File

@ -0,0 +1,2 @@
import pkg_resources
pkg_resources.declare_namespace(__name__)

View File

@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
from datetime import timedelta, datetime
import re
from django.shortcuts import redirect
from django.utils.translation import ugettext as _
from django.contrib import messages
from .views import SecretQuestionWizard
from .conf import SQ_SESSION_KEY, SQ_TOKEN_TTL
def secret_questions_required(ttl=SQ_TOKEN_TTL):
def _inner(view):
def _wrapped(request, *args, **kwargs):
session_token, url, date = request.session.get(SQ_SESSION_KEY,
(None,
None,
datetime.now(),))
get_token = request.GET.get(SQ_SESSION_KEY, None)
date_max = date + timedelta(seconds=ttl)
if session_token is None or get_token is None:
wiz = SecretQuestionWizard(request)
return wiz(request, *args, **kwargs)
if date_max < datetime.now() or \
not request.get_full_path().startswith(url):
if request.method == "POST":
messages.error(request,
_("Your modifications were canceled."))
url = request.get_full_path()
regex_no_session_key = "(.*)%s=[a..z0..9]*(.*)" % \
SQ_SESSION_KEY
clean_url = re.sub(regex_no_session_key, "\\1", url)
return redirect(clean_url)
if session_token == get_token:
return view(request, *args, **kwargs)
# should not be raised
raise Exception('SQ') # pragma: no cover
return _wrapped
return _inner

View File

@ -0,0 +1,3 @@
from .configuration import ConfigurationTest
from .use import UseTest
from .token import TokenTest

View File

@ -0,0 +1,92 @@
# -*- coding: utf-8 -*-
import re
from django.test import TestCase
from django.test.client import Client
from django.contrib.auth.models import User
from auf.django.secretquestions.models import Question, Answer, crypt_answer
class SecretQuestionTest(TestCase):
client = Client()
username = 'paul'
password = 'lemay'
def setUp(self):
self.create_user()
self.create_questions()
def create_user(self):
self.user = User.objects.create(username=self.username)
self.user.set_password(self.password)
self.user.save()
def create_questions(self):
self.question1 = Question.objects.create(text="question1")
self.question1.save()
self.question2 = Question.objects.create(text="question2")
self.question2.save()
def create_answers(self):
self.answer1 = Answer.objects.create(question=self.question1,
secret=crypt_answer('one'),
user=self.user)
self.answer1.save()
self.answer2 = Answer.objects.create(question=self.question2,
secret=crypt_answer('two'),
user=self.user)
self.answer2.save()
def _get_hashs(self, response):
"""
Parse response to prepare POST according previous hash
"""
regex_hash = 'name="(hash_[0-9])+" value="([a-z0-9]+)"'
found = re.findall(regex_hash, response.content)
hashs = {}
for k, v in found:
hashs.update({k: v})
return hashs
def get_response_from_final_step(self, url):
self.create_answers()
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
data = {'wizard_step': 0,
'0-username': self.username, }
response = self.client.post(url, data)
self.assertEqual(response.status_code, 200)
self.assertTrue(self.question1.text in response.content)
# wrong response
data = {'wizard_step': 1,
'0-username': self.username,
'1-raw_answer': 'wrong answer', }
data.update(self._get_hashs(response))
response = self.client.post(url, data)
self.assertEqual(response.status_code, 200)
self.assertFalse('2-raw_answer' in response.content)
# good response
data = {'wizard_step': 1,
'0-username': self.username,
'1-raw_answer': 'one', }
data.update(self._get_hashs(response))
response = self.client.post(url, data)
self.assertEqual(response.status_code, 200)
self.assertTrue('2-raw_answer' in response.content)
# good response
data = {'wizard_step': 2,
'0-username': self.username,
'1-raw_answer': 'one',
'2-raw_answer': 'two', }
data.update(self._get_hashs(response))
response = self.client.post(url, data)
return response

View File

@ -3,8 +3,9 @@
from django.core.urlresolvers import reverse
from django.conf import settings
from secretquestions.tests.common import SecretQuestionTest
from secretquestions.models import Answer
from auf.django.secretquestions.models import Answer
from .common import SecretQuestionTest
class ConfigurationTest(SecretQuestionTest):
@ -55,6 +56,30 @@ class ConfigurationTest(SecretQuestionTest):
self.assertNotEqual(answer.secret, raw_password)
self.assertNotEqual(answer.secret, '')
def test_setting_2_same_questions(self):
"""
Check if error is raised if you choose 2 same questions
"""
raw_password = 'xxx'
self.assertEqual(self.client.login(username=self.username,
password=self.password), True)
url = reverse('sq_setup')
data = {'form-TOTAL_FORMS': u'2',
'form-INITIAL_FORMS': u'0',
'form-MAX_NUM_FORMS': u'',
'form-0-question': self.question1.id,
'form-0-secret': raw_password,
'form-1-question': self.question1.id,
'form-1-secret': raw_password, }
response = self.client.post(url, data)
self.assertEqual(response.status_code, 200)
answers = Answer.objects.filter(user=self.user)
self.assertEqual(len(answers), 0)
self.assertTrue(
"Each question has to be different." in response.content)
def test_setting_empty_answer_for_one_question(self):
"""
Check if the answer is not empty

View File

@ -1,8 +1,10 @@
# -*- coding: utf-8 -*-
USE_I18N = False
SECRET_KEY = 'secret'
ROOT_URLCONF = 'secretquestions.tests.urls'
ROOT_URLCONF = 'auf.django.secretquestions.tests.urls'
DATABASES = {'default':
{'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:', }}
@ -12,4 +14,4 @@ INSTALLED_APPS = ('django.contrib.auth',
'django.contrib.sessions',
'django.contrib.admin',
'registration',
'secretquestions',)
'auf.django.secretquestions',)

View File

@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-
import time
from django.core.urlresolvers import reverse
from .common import SecretQuestionTest
from .views import TTL
class TokenTest(SecretQuestionTest):
"""
TestCase for token testing
"""
def test_expiracy(self):
"""
Check if you try to access page after X times.
"""
url = reverse('sq_test_private_ttl')
response = self.get_response_from_final_step(url)
location = response['location']
response = self.client.get(location)
self.assertEqual(response.status_code, 200)
self.assertTrue('OK' in response.content)
time.sleep(TTL+1)
response = self.client.get(location)
self.assertEqual(response.status_code, 302)
redirect = response['location'].replace('http://testserver', '')
self.assertEqual(redirect, url)
def test_warning(self):
"""
Check if you try to access page after X times.
"""
url = reverse('sq_test_private_ttl')
response = self.get_response_from_final_step(url)
location = response['location']
response = self.client.get(location)
self.assertEqual(response.status_code, 200)
self.assertTrue('OK' in response.content)
time.sleep(TTL+1)
response = self.client.post(location, {})
self.assertEqual(response.status_code, 302)
redirect = response['location'].replace('http://testserver', '')
self.assertEqual(redirect, url)
response = self.client.get(url)
messages = [m.message for m in response.context['messages']]
self.assertTrue("Your modifications were canceled." in messages)

View File

@ -0,0 +1,21 @@
from django.conf.urls.defaults import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns(
'',
(r'^admin/(.*)', include(admin.site.urls)),
(r'^accounts/', include('registration.urls')),
(r'^secret/',
include('auf.django.secretquestions.urls')),
url(r'^test_public/',
'auf.django.secretquestions.tests.views.public',
name='sq_test_public'),
url(r'^test_private/',
'auf.django.secretquestions.tests.views.private',
name='sq_test_private'),
url(r'^test_private_ttl/',
'auf.django.secretquestions.tests.views.private_ttl',
name='sq_test_private_ttl'),)

View File

@ -1,11 +1,10 @@
# -*- coding: utf-8 -*-
import re
from django.core.urlresolvers import reverse
from secretquestions.tests.common import SecretQuestionTest
from secretquestions.conf import SQ_SESSION_KEY
from auf.django.secretquestions import conf
from .common import SecretQuestionTest
class UseTest(SecretQuestionTest):
@ -72,7 +71,7 @@ class UseTest(SecretQuestionTest):
self.assertFalse('OK' in response.content)
self.assertFalse('username' in response.content)
self.assertTrue(url in response['location'])
self.assertTrue(SQ_SESSION_KEY in response['location'])
self.assertTrue(conf.SQ_SESSION_KEY in response['location'])
def test_username_form(self):
"""
@ -91,18 +90,7 @@ class UseTest(SecretQuestionTest):
response = self.client.post(url, data)
self.assertEqual(response.status_code, 302)
self.assertTrue(url in response['location'])
self.assertTrue(SQ_SESSION_KEY in response['location'])
def _get_hashs(self, response):
"""
Parse response to prepare POST according previous hash
"""
regex_hash = 'name="(hash_[0-9])+" value="([a-z0-9]+)"'
found = re.findall(regex_hash, response.content)
hashs = {}
for k, v in found:
hashs.update({k: v})
return hashs
self.assertTrue(conf.SQ_SESSION_KEY in response['location'])
def test_question_form(self):
"""
@ -146,7 +134,7 @@ class UseTest(SecretQuestionTest):
response = self.client.post(url, data)
self.assertEqual(response.status_code, 302)
self.assertTrue(url in response['location'])
self.assertTrue(SQ_SESSION_KEY in response['location'])
self.assertTrue(conf.SQ_SESSION_KEY in response['location'])
response = self.client.get(response['location'])
self.assertTrue('OK' in response.content)

View File

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
from django.http import HttpResponse
from auf.django.secretquestions.decorators import secret_questions_required
TTL = 1
def public(request):
return HttpResponse("OK")
@secret_questions_required()
def private(request):
return HttpResponse("OK")
@secret_questions_required(ttl=TTL)
def private_ttl(request):
return HttpResponse("OK")

View File

@ -4,5 +4,5 @@ from django.conf.urls.defaults import patterns, url
urlpatterns = patterns('',
url(r'questions/setup$',
'secretquestions.views.setup_form',
'auf.django.secretquestions.views.setup_form',
name="sq_setup"), )

View File

@ -1,43 +0,0 @@
# -*- coding: utf-8 -*-
from datetime import timedelta, datetime
import re
from django.shortcuts import redirect
from django.utils.translation import ugettext as _
from django.contrib import messages
from .views import SecretQuestionWizard
from .conf import SQ_SESSION_KEY, SQ_TOKEN_TTL
def secret_questions_required(view, ttl=SQ_TOKEN_TTL):
def _wrapped(request, *args, **kwargs):
session_token, url, date = request.session.get(SQ_SESSION_KEY,
(None,
None,
datetime.now()
))
get_token = request.GET.get(SQ_SESSION_KEY, None)
date_max = date + timedelta(seconds=ttl)
if session_token is None or get_token is None:
wiz = SecretQuestionWizard(request)
return wiz(request, *args, **kwargs)
if date_max < datetime.now() or \
not request.get_full_path().startswith(url):
if request.method == "POST":
messages.error(request, _("Your modifications were canceled."))
url = request.get_full_path()
regex_no_session_key = "(.*)%s=[a..z0..9]*(.*)" % SQ_SESSION_KEY
clean_url = re.sub(regex_no_session_key, "\\1", url)
return redirect(clean_url)
if session_token == get_token:
return view(request, *args, **kwargs)
raise Exception('SQ')
return _wrapped

View File

@ -1,2 +0,0 @@
from configuration import ConfigurationTest
from use import UseTest

View File

@ -1,40 +0,0 @@
# -*- coding: utf-8 -*-
from django.test import TestCase
from django.test.client import Client
from django.contrib.auth.models import User
from secretquestions.models import Question, Answer, crypt_answer
class SecretQuestionTest(TestCase):
client = Client()
username = 'paul'
password = 'lemay'
def setUp(self):
self.create_user()
self.create_questions()
def create_user(self):
self.user = User.objects.create(username=self.username)
self.user.set_password(self.password)
self.user.save()
def create_questions(self):
self.question1 = Question.objects.create(text="question1")
self.question1.save()
self.question2 = Question.objects.create(text="question2")
self.question2.save()
def create_answers(self):
self.answer1 = Answer.objects.create(question=self.question1,
secret=crypt_answer('one'),
user=self.user)
self.answer1.save()
self.answer2 = Answer.objects.create(question=self.question2,
secret=crypt_answer('two'),
user=self.user)
self.answer2.save()

View File

@ -1,16 +0,0 @@
from django.conf.urls.defaults import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
(r'^admin/(.*)', include(admin.site.urls)),
(r'^accounts/', include('registration.urls')),
(r'^secret/', include('secretquestions.urls')),
url(r'^test_public/',
'secretquestions.tests.views.public',
name='sq_test_public'),
url(r'^test_private/',
'secretquestions.tests.views.private',
name='sq_test_private'),)

View File

@ -1,14 +0,0 @@
# -*- coding: utf-8 -*-
from django.http import HttpResponse
from secretquestions.decorators import secret_questions_required
def public(request):
return HttpResponse("OK")
@secret_questions_required
def private(request):
return HttpResponse("OK")

View File

@ -2,8 +2,9 @@ from setuptools import setup, find_packages
import sys, os
version = '0.0'
name = 'auf.django.secretquestions'
setup(name='django-secretquestions',
setup(name=name,
version=version,
description="Provides secret questions toolkit",
long_description="""\
@ -12,9 +13,10 @@ setup(name='django-secretquestions',
keywords='django secretquestions authentication security',
author='Olivier Larchev\xc3\xaaque',
author_email='olivier.larcheveque@auf.org',
url='',
license='',
url='http://pypi.auf.org/%s' % name,
license='GPL',
packages=find_packages(exclude=['ez_setup', 'examples', 'tests']),
namespace_packages = ['auf'],
include_package_data=True,
zip_safe=False,
install_requires=[

12
tox.ini
View File

@ -1,5 +1,5 @@
[tox]
envlist = django1.3, django1.4
envlist = django1.3
[testenv]
deps =
@ -9,16 +9,12 @@ deps =
commands =
coverage erase
coverage run --source="{envsitepackagesdir}/secretquestions/" {envdir}/bin/django-admin.py test secretquestions --settings=secretquestions.tests.settings
pep8 -r --statistics --count {envsitepackagesdir}/secretquestions/ --exclude={envsitepackagesdir}/secretquestions/migrations/*
coverage run --source="{envsitepackagesdir}/auf/django/secretquestions/" {envdir}/bin/django-admin.py test secretquestions --settings=auf.django.secretquestions.tests.settings
pep8 -r --statistics --count {envsitepackagesdir}/auf/django/secretquestions/ --exclude={envsitepackagesdir}/auf/django/secretquestions/migrations/*
coverage report
coverage html
[testenv:django1.3]
deps =
{[testenv]deps}
django==1.3
[testenv:django1.4]
deps =
{[testenv]deps}
django==1.4