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