model + setup form
This commit is contained in:
commit
de5e37d266
|
@ -0,0 +1,2 @@
|
||||||
|
*egg-info
|
||||||
|
*.pyc
|
|
@ -0,0 +1 @@
|
||||||
|
#
|
|
@ -0,0 +1,7 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
from .models import Question
|
||||||
|
|
||||||
|
admin.site.register(Question)
|
|
@ -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()
|
|
@ -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']
|
|
@ -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')
|
|
@ -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 %}
|
|
@ -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'),
|
||||||
|
)
|
|
@ -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
|
|
@ -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: -*-
|
||||||
|
""",
|
||||||
|
)
|
Reference in New Issue