model + setup form

This commit is contained in:
Olivier Larchevêque 2013-08-06 11:32:05 -04:00
commit de5e37d266
12 changed files with 281 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*egg-info
*.pyc

View File

@ -0,0 +1 @@
#

7
secretquestions/admin.py Normal file
View File

@ -0,0 +1,7 @@
# -*- coding: utf-8 -*-
from django.contrib import admin
from .models import Question
admin.site.register(Question)

64
secretquestions/forms.py Normal file
View File

@ -0,0 +1,64 @@
# -*- coding: utf-8 -*-
from django.conf import settings
from django import forms
from django.forms.models import modelformset_factory, ModelForm
from django.utils.translation import ugettext as _
from .models import Answer, crypt_answer
MAX_SECRET_QUESTIONS = getattr(settings, 'MAX_SECRET_QUESTIONS', 3)
class AnswerForm(ModelForm):
class Meta:
model = Answer
def __init__(self, *args, **kwargs):
if 'instance' in kwargs:
kwargs['instance'].secret = ""
super(AnswerForm, self).__init__(*args, **kwargs)
def clean_secret(self):
data = self.cleaned_data['secret']
return crypt_answer(data)
_FreeAnswerFormSet = modelformset_factory(Answer, form=AnswerForm,
fields=("question", "secret"),
extra=MAX_SECRET_QUESTIONS,
max_num=MAX_SECRET_QUESTIONS,
can_delete=False)
class AnswerFormSet(_FreeAnswerFormSet):
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user')
super(AnswerFormSet, self).__init__(*args, **kwargs)
def save_all(self):
instances = self.save(commit=False)
for instance in instances:
instance.user = self.user
instance.save()
def clean(self):
questions = []
for i in range(0, self.total_form_count()):
form = self.forms[i]
try:
question = form.cleaned_data.get('question')
except:
question = None
if question is None:
raise forms.ValidationError(
_("All questions have to be selected."))
if question in questions:
raise forms.ValidationError(
_("Each question has to be different."))
questions.append(question)
return super(AnswerFormSet, self).clean()

View File

@ -0,0 +1,87 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model 'Question'
db.create_table('secretquestions_question', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('text', self.gf('django.db.models.fields.CharField')(max_length=255)),
))
db.send_create_signal('secretquestions', ['Question'])
# Adding model 'Answer'
db.create_table('secretquestions_answer', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
('question', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['secretquestions.Question'])),
('secret', self.gf('django.db.models.fields.CharField')(max_length=255)),
))
db.send_create_signal('secretquestions', ['Answer'])
def backwards(self, orm):
# Deleting model 'Question'
db.delete_table('secretquestions_question')
# Deleting model 'Answer'
db.delete_table('secretquestions_answer')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'secretquestions.answer': {
'Meta': {'object_name': 'Answer'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'question': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['secretquestions.Question']"}),
'secret': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
},
'secretquestions.question': {
'Meta': {'object_name': 'Question'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'text': ('django.db.models.fields.CharField', [], {'max_length': '255'})
}
}
complete_apps = ['secretquestions']

View File

29
secretquestions/models.py Normal file
View File

@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
from django.db import models
from django.contrib.auth.models import get_hexdigest
def crypt_answer(raw):
import random
algo = 'sha1'
salt = get_hexdigest(algo, str(random.random()), str(random.random()))[:5]
hsh = get_hexdigest(algo, salt, raw)
return '%s$%s$%s' % (algo, salt, hsh)
class Question(models.Model):
text = models.CharField(max_length=255)
def __unicode__(self):
return self.text
class Answer(models.Model):
user = models.ForeignKey('auth.User')
question = models.ForeignKey('secretquestions.Question')
secret = models.CharField(max_length=255)
class Meta:
unique_together = ('question', 'user')

View File

@ -0,0 +1,23 @@
{% extends "base.html" %}
{% load i18n %}
{% block content %}
<p>
{% blocktrans %}
Select several questions and register your secret answers.
These one will be asked to you for some critical features which required more
security to ensure that is you.
{% endblocktrans %}
</p>
{{ formset.non_form_errors.as_ul }}
<form action="" method="post">{% csrf_token %}
<table>
{{ formset }}
</table>
<input type="submit" value="{% trans "Save all" %}" />
</form>
{% endblock content %}

8
secretquestions/urls.py Normal file
View File

@ -0,0 +1,8 @@
# -*- coding: utf-8 -*-
from django.conf.urls.defaults import patterns
urlpatterns = patterns('',
(r'questions/setup$', 'secretquestions.views.setup_form'),
(r'questions/ask$','secretquestions.views.ask_form'),
)

31
secretquestions/views.py Normal file
View File

@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
from django.template import RequestContext
from django.shortcuts import render_to_response, redirect
from django.conf import settings
from django.utils.translation import ugettext as _
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from .forms import AnswerFormSet
@login_required
def setup_form(request):
if request.method == 'POST':
formset = AnswerFormSet(request.POST, user=request.user)
if formset.is_valid():
formset.save_all()
messages.info(request, _("Your secret answers were successfully saved."))
return redirect(settings.LOGIN_REDIRECT_URL)
else:
formset = AnswerFormSet(user=request.user)
return render_to_response("secretquestions/setup_form.html", {
"formset": formset,
},
context_instance=RequestContext(request))
def ask_form(request):
pass

3
setup.cfg Normal file
View File

@ -0,0 +1,3 @@
[egg_info]
tag_build = dev
tag_svn_revision = true

26
setup.py Normal file
View File

@ -0,0 +1,26 @@
from setuptools import setup, find_packages
import sys, os
version = '0.0'
setup(name='django-secretquestions',
version=version,
description="Provides secret questions toolkit",
long_description="""\
""",
classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
keywords='django secretquestions authentication security',
author='Olivier Larchev\xc3\xaaque',
author_email='olivier.larcheveque@auf.org',
url='',
license='',
packages=find_packages(exclude=['ez_setup', 'examples', 'tests']),
include_package_data=True,
zip_safe=False,
install_requires=[
# -*- Extra requirements: -*-
],
entry_points="""
# -*- Entry points: -*-
""",
)