rename package finish testing
This commit is contained in:
parent
6ef2d78904
commit
37a05844fb
|
@ -1 +1 @@
|
|||
recursive-include secretquestions/templates *
|
||||
recursive-include auf/django/secretquestions/templates *
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
import pkg_resources
|
||||
pkg_resources.declare_namespace(__name__)
|
|
@ -0,0 +1,2 @@
|
|||
import pkg_resources
|
||||
pkg_resources.declare_namespace(__name__)
|
|
@ -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
|
|
@ -0,0 +1,3 @@
|
|||
from .configuration import ConfigurationTest
|
||||
from .use import UseTest
|
||||
from .token import TokenTest
|
|
@ -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
|
|
@ -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
|
|
@ -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',)
|
|
@ -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)
|
|
@ -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'),)
|
|
@ -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)
|
|
@ -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")
|
|
@ -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"), )
|
|
@ -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
|
|
@ -1,2 +0,0 @@
|
|||
from configuration import ConfigurationTest
|
||||
from use import UseTest
|
|
@ -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()
|
|
@ -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'),)
|
|
@ -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")
|
8
setup.py
8
setup.py
|
@ -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
12
tox.ini
|
@ -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
|
||||
|
|
Reference in New Issue