Add htpasswd management functionality.
- Legacy-Id: 3386
This commit is contained in:
parent
f47ca8710c
commit
6c93e2553b
125
ietf/ietfauth/forms.py
Normal file
125
ietf/ietfauth/forms.py
Normal file
|
@ -0,0 +1,125 @@
|
|||
import datetime
|
||||
import hashlib
|
||||
import subprocess
|
||||
|
||||
from django import forms
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth.forms import PasswordResetForm
|
||||
from django.contrib.sites.models import Site
|
||||
from django.utils.translation import ugettext, ugettext_lazy as _
|
||||
|
||||
from ietf.utils.mail import send_mail
|
||||
from ietf.utils import debug
|
||||
#from redesign.person.models import Person, Email
|
||||
|
||||
|
||||
class RegistrationForm(forms.Form):
|
||||
|
||||
email = forms.EmailField(label="Your email")
|
||||
realm = 'IETF'
|
||||
expire = 3
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
self.send_email()
|
||||
return True
|
||||
|
||||
def send_email(self):
|
||||
domain = Site.objects.get_current().domain
|
||||
subject = 'Confirm registration at %s' % domain
|
||||
from_email = settings.DEFAULT_FROM_EMAIL
|
||||
to_email = self.cleaned_data['email']
|
||||
today = datetime.date.today().strftime('%Y%m%d')
|
||||
auth = hashlib.md5('%s%s%s%s' % (settings.SECRET_KEY, today, to_email, self.realm)).hexdigest()
|
||||
context = {
|
||||
'domain': domain,
|
||||
'today': today,
|
||||
'realm': self.realm,
|
||||
'auth': auth,
|
||||
'username': to_email,
|
||||
'expire': settings.DAYS_TO_EXPIRE_REGISTRATION_LINK,
|
||||
}
|
||||
send_mail(None, to_email, from_email, subject, 'registration/creation_email.txt', context)
|
||||
|
||||
def clean_email(self):
|
||||
email = self.cleaned_data.get('email', '')
|
||||
if not email:
|
||||
return email
|
||||
# if User.objects.filter(username=email).count():
|
||||
# raise forms.ValidationError(_('Email already in use'))
|
||||
return email
|
||||
|
||||
|
||||
class RecoverPasswordForm(RegistrationForm):
|
||||
|
||||
realm = 'IETF'
|
||||
|
||||
def send_email(self):
|
||||
domain = Site.objects.get_current().domain
|
||||
subject = 'Password reset at %s' % domain
|
||||
from_email = settings.DEFAULT_FROM_EMAIL
|
||||
today = datetime.date.today().strftime('%Y%m%d')
|
||||
to_email = self.cleaned_data['email']
|
||||
today = datetime.date.today().strftime('%Y%m%d')
|
||||
auth = hashlib.md5('%s%s%s%s' % (settings.SECRET_KEY, today, to_email, self.realm)).hexdigest()
|
||||
context = {
|
||||
'domain': domain,
|
||||
'today': today,
|
||||
'realm': self.realm,
|
||||
'auth': auth,
|
||||
'username': to_email,
|
||||
'expire': settings.DAYS_TO_EXPIRE_REGISTRATION_LINK,
|
||||
}
|
||||
send_mail(None, to_email, from_email, subject, 'registration/password_reset_email.txt', context)
|
||||
|
||||
|
||||
class PasswordForm(forms.Form):
|
||||
|
||||
password1 = forms.CharField(label=_("Password"), widget=forms.PasswordInput)
|
||||
password2 = forms.CharField(label=_("Password confirmation"), widget=forms.PasswordInput,
|
||||
help_text=_("Enter the same password as above, for verification."))
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.username = kwargs.pop('username')
|
||||
self.update_user = kwargs.pop('update_user', False)
|
||||
super(PasswordForm, self).__init__(*args, **kwargs)
|
||||
|
||||
def clean_password2(self):
|
||||
password1 = self.cleaned_data.get("password1", "")
|
||||
password2 = self.cleaned_data["password2"]
|
||||
if password1 != password2:
|
||||
raise forms.ValidationError(_("The two password fields didn't match."))
|
||||
return password2
|
||||
|
||||
def get_password(self):
|
||||
return self.cleaned_data.get('password1')
|
||||
|
||||
def create_user(self):
|
||||
# user = User.objects.create(username=self.username,
|
||||
# email=self.username)
|
||||
# person = Person.objects.create(user=user,
|
||||
# name=self.username,
|
||||
# ascii=self.username)
|
||||
# Email.objects.create(person=person,
|
||||
# address=self.username)
|
||||
# return user
|
||||
return None
|
||||
|
||||
def get_user(self):
|
||||
return User.objects.get(username=self.username)
|
||||
|
||||
@debug.trace
|
||||
def save(self):
|
||||
# if self.update_user:
|
||||
# user = self.get_user()
|
||||
# else:
|
||||
# user = self.create_user()
|
||||
# user.set_password(self.get_password())
|
||||
# user.save()
|
||||
# return user
|
||||
debug.show("[settings.HTPASSWD_COMMAND, settings.HTPASSWD_FILE, self.username, self.get_password()]")
|
||||
p = subprocess.Popen([settings.HTPASSWD_COMMAND, "-b", settings.HTPASSWD_FILE, self.username, self.get_password()], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
stdout, stderr = p.communicate()
|
||||
debug.show('stdout')
|
||||
debug.show('stderr')
|
||||
return p.returncode
|
|
@ -1,11 +1,21 @@
|
|||
# Copyright The IETF Trust 2007, 2009, All Rights Reserved
|
||||
|
||||
from django.conf.urls.defaults import patterns
|
||||
from django.conf.urls.defaults import patterns, url
|
||||
from ietf.ietfauth import views
|
||||
|
||||
urlpatterns = patterns('',
|
||||
(r'^$', views.index, None, 'account_index'),
|
||||
(r'^login/$', views.ietf_login),
|
||||
(r'^loggedin/$', views.ietf_loggedin),
|
||||
(r'^profile/$', views.profile),
|
||||
# (r'^login/(?P<user>[a-z0-9.@]+)/(?P<passwd>.+)$', views.url_login),
|
||||
)
|
||||
|
||||
urlpatterns += patterns('ietf.ietfauth.views',
|
||||
url(r'^create/$', 'create_account', name='create_account'),
|
||||
url(r'^confirm/(?P<username>[\w.@+-]+)/(?P<date>[\d]+)/(?P<realm>[\w]+)/(?P<registration_hash>[a-f0-9]+)/$', 'confirm_account', name='confirm_account'),
|
||||
url(r'^reset/$', 'password_reset_view', name='password_reset'),
|
||||
url(r'^reset/confirm/(?P<username>[\w.@+-]+)/(?P<date>[\d]+)/(?P<realm>[\w]+)/(?P<reset_hash>[a-f0-9]+)/$', 'confirm_password_reset', name='confirm_password_reset'),
|
||||
url(r'^ajax/check_username/$', 'ajax_check_username', name='ajax_check_username'),
|
||||
|
||||
)
|
||||
|
|
|
@ -32,15 +32,28 @@
|
|||
|
||||
# Copyright The IETF Trust 2007, All Rights Reserved
|
||||
|
||||
import datetime
|
||||
import hashlib
|
||||
|
||||
from django.template import RequestContext
|
||||
from django.shortcuts import render_to_response
|
||||
from django.http import HttpResponse, Http404, HttpResponseRedirect
|
||||
from django.shortcuts import get_object_or_404, render_to_response
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.http import HttpResponseRedirect, HttpResponse
|
||||
from django.contrib.auth import REDIRECT_FIELD_NAME, authenticate, login
|
||||
from django.contrib.auth.models import User
|
||||
from django.conf import settings
|
||||
from django.utils.http import urlquote
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.utils import simplejson as json
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from forms import (RegistrationForm, PasswordForm, RecoverPasswordForm)
|
||||
|
||||
|
||||
def index(request):
|
||||
return render_to_response('registration/index.html', context_instance=RequestContext(request))
|
||||
|
||||
def url_login(request, user, passwd):
|
||||
user = authenticate(username=user, password=passwd)
|
||||
redirect_to = request.REQUEST.get(REDIRECT_FIELD_NAME, '')
|
||||
|
@ -70,3 +83,82 @@ def ietf_loggedin(request):
|
|||
@login_required
|
||||
def profile(request):
|
||||
return render_to_response('registration/profile.html', context_instance=RequestContext(request))
|
||||
|
||||
|
||||
def create_account(request):
|
||||
success = False
|
||||
if request.method == 'POST':
|
||||
form = RegistrationForm(request.POST)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
success = True
|
||||
else:
|
||||
form = RegistrationForm()
|
||||
return render_to_response('registration/create.html',
|
||||
{'form': form,
|
||||
'success': success},
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
||||
def confirm_account(request, username, date, realm, registration_hash):
|
||||
valid = hashlib.md5('%s%s%s%s' % (settings.SECRET_KEY, date, username, realm)).hexdigest() == registration_hash
|
||||
if not valid:
|
||||
raise Http404
|
||||
request_date = datetime.date(int(date[:4]), int(date[4:6]), int(date[6:]))
|
||||
if datetime.date.today() > (request_date + datetime.timedelta(days=settings.DAYS_TO_EXPIRE_REGISTRATION_LINK)):
|
||||
raise Http404
|
||||
success = False
|
||||
if request.method == 'POST':
|
||||
form = PasswordForm(request.POST, username=username)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
# TODO: Add the user in the htdigest file
|
||||
success = True
|
||||
else:
|
||||
form = PasswordForm(username=username)
|
||||
return render_to_response('registration/confirm.html',
|
||||
{'form': form, 'email': username, 'success': success},
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
||||
def password_reset_view(request):
|
||||
success = False
|
||||
if request.method == 'POST':
|
||||
form = RecoverPasswordForm(request.POST)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
success = True
|
||||
else:
|
||||
form = RecoverPasswordForm()
|
||||
return render_to_response('registration/password_reset.html',
|
||||
{'form': form,
|
||||
'success': success},
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
||||
def confirm_password_reset(request, username, date, realm, reset_hash):
|
||||
valid = hashlib.md5('%s%s%s%s' % (settings.SECRET_KEY, date, username, realm)).hexdigest() == reset_hash
|
||||
if not valid:
|
||||
raise Http404
|
||||
success = False
|
||||
if request.method == 'POST':
|
||||
form = PasswordForm(request.POST, update_user=True, username=username)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
# TODO: Update the user in the htdigest file
|
||||
success = True
|
||||
else:
|
||||
form = PasswordForm(username=username)
|
||||
return render_to_response('registration/change_password.html',
|
||||
{'form': form,
|
||||
'success': success,
|
||||
'username': username},
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
def ajax_check_username(request):
|
||||
username = request.GET.get('username', '')
|
||||
error = False
|
||||
if User.objects.filter(username=username).count():
|
||||
error = _('This email is already in use')
|
||||
return HttpResponse(simplejson.dumps({'error': error}), mimetype='text/plain')
|
||||
|
|
@ -229,6 +229,11 @@ MAX_DAILY_SUBMISSION = 1000
|
|||
MAX_DAILY_SUBMISSION_SIZE = 2000
|
||||
# End of ID Submission Tool settings
|
||||
|
||||
# Account settings
|
||||
DAYS_TO_EXPIRE_REGISTRATION_LINK = 3
|
||||
HTPASSWD_COMMAND = "/usr/bin/htpasswd2"
|
||||
HTPASSWD_FILE = "/www/htpasswd"
|
||||
|
||||
# Put SECRET_KEY in here, or any other sensitive or site-specific
|
||||
# changes. DO NOT commit settings_local.py to svn.
|
||||
from settings_local import *
|
||||
|
|
|
@ -35,6 +35,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
{% load wg_menu %}
|
||||
{% load ietf_filters %}
|
||||
<ul>
|
||||
<li class="sect first">Accounts</li>
|
||||
<li><a href="{% url account_index %}">New Account</a></li>
|
||||
{% if user|in_group:"Area_Director" %}
|
||||
<li class="sect first">AD Dashboard</li>
|
||||
<li><a href="{% url doc_search_by_ad name=user.get_profile.person.full_name_as_key %}">My Documents</a></li>
|
||||
|
|
Loading…
Reference in a new issue