You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

253 lines
10 KiB

# -*- coding: utf-8 -*-
import hashlib
from datetime import datetime
from dateutil.relativedelta import relativedelta
from random import random
from django.shortcuts import render, redirect, get_object_or_404
from django.core.urlresolvers import reverse
from django.views.decorators.csrf import csrf_protect
from django.views.decorators.debug import sensitive_variables, sensitive_post_parameters
from django.contrib import auth
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.conf import settings
from django.contrib.sessions.models import Session
from django.contrib.auth.views import logout as django_logout
from project.customer.models import UserProfile, UserProfileFilters, License
from . import forms, models, emails
REGISTRATION_OPEN = getattr(settings, 'REGISTRATION_OPEN', True)
@sensitive_variables()
def _create_user(request, **kwargs):
# создать юзера
email, password = kwargs['email'], kwargs['password1']
# сгенерировать имя пользователя. на всякий случай, добавить к нему соль, чтобы снизить вероятность коллизий
username = hashlib.sha1(u'%s%s' % (email, random())).hexdigest()[:30]
user = models.DokUser.objects.create_user(username=username, email=email, password=password)
# создать пустой профиль
profile_type = kwargs['profile_type']
profile = UserProfile.objects.create_profile(profile_type=profile_type)
user.profile = profile
user.save()
# создать фильтры профиля
UserProfileFilters.objects.create_filters(user=user)
# создать запись, что email не подтверждён
models.ConfirmEmail.objects.unconfirm(user)
# аутентифицировать и залогинить
new_user = auth.authenticate(username=username, password=password)
#auth.login(request, new_user)
return new_user
@sensitive_variables()
@sensitive_post_parameters()
@csrf_protect
def register(request):
"""
Регистрация нового пользователя.
Алгоритм регистрации такой:
- юзер в форме вводит свой email, пароль и форму собственности;
- форма сабмитится во вьюху и проверяется на валидность;
- генерится хеш по юзерскому email - т.к. регистрация и логин по email, а поле User.username всего лишь 30 символов,
то храню email не в нем, а в соответсвующем поле, ну а username генерирую "левый";
- создается юзер, пока с пустым профилем;
- юзера аутентифицирует и логинит в систему;
- после чего редиректит на страницу редактирования профиля.
"""
form_class = forms.RegistrationForm
form_prefix = 'register'
template_name = 'myauth/register.html'
success_url = 'myauth_login'
success_msg = u'Дождитесь письма на указанный Вами адрес и перейдите по ссылке в письме.'
registration_closed_url = 'myauth_registration_closed'
if not REGISTRATION_OPEN:
return redirect(registration_closed_url)
if request.method == 'POST':
form = form_class(data=request.POST, prefix=form_prefix)
if form.is_valid():
new_user = _create_user(request, **form.cleaned_data)
confirm_url = reverse('myauth_confirm_email', args=[new_user.username,])
emails.send_registration_email.delay(new_user.email, confirm_url)
messages.add_message(request, messages.INFO, success_msg)
return redirect(success_url)
else:
form = form_class(prefix=form_prefix)
return render(request, template_name, {'form': form,})
@sensitive_variables()
def confirm_registered_email(request, key):
"""Подтверждение зарегистрированного email."""
success_url = 'customer_profile_edit'
success_msg = u'E-mail подтверждён.'
user = get_object_or_404(models.DokUser, username__iexact = key) # ключ = имя пользователя
models.ConfirmEmail.objects.confirm(user)
messages.add_message(request, messages.INFO, success_msg)
licenses = License.objects.filter(company=user.profile)
if not licenses:
license = License(company=user.profile, date_from=datetime.today(),
date_to=datetime.today() + relativedelta(days=44),
pay_sum=0,
term=0,
status=-1, payform=-1)
license.save()
user.profile.confirmed = True
user.profile.active = True
user.profile.save()
auth.logout(request)
return redirect(success_url)
@sensitive_variables()
@sensitive_post_parameters()
@csrf_protect
def reset(request):
"""Запросить ключ восстановления пароля."""
form_class = forms.ResetPasswordForm
form_prefix='reset'
template_name = 'myauth/reset.html'
success_url = 'myauth_reset_key_ready'
if request.method == 'POST':
form = form_class(data=request.POST, prefix=form_prefix)
if form.is_valid():
user = form.get_user()
key = models.ResetKey.objects.create_key(user)
confirm_url = reverse('myauth_confirm_reset', args=[key.key,])
emails.send_reset_password_email.delay(user.email, confirm_url)
return redirect(success_url)
else:
form = form_class(prefix=form_prefix)
return render(request, template_name, {'form': form,})
@sensitive_variables()
def confirm_reset(request, key):
"""Подтверждение запроса на восстановление пароля.
Генерирует новый пароль и отправляет его на почту пользователю.
"""
success_url = 'customer_profile_view'
success_msg = u'Новый пароль выслан на ваш e-mail.'
key = get_object_or_404(models.ResetKey, key__iexact = key)
new_password = User.objects.make_random_password() # новый пароль
key.user.set_password(new_password)
key.user.save()
emails.send_new_password_email.delay(key.user.email, new_password)
key.delete() # удалить ключ восстановления пароля
messages.add_message(request, messages.INFO, success_msg)
return redirect(success_url)
@sensitive_variables()
@sensitive_post_parameters()
@login_required
@csrf_protect
def change_password(request):
form_class = forms.ChangePasswordForm
form_prefix = 'change_password'
template_name = 'myauth/change_password.html'
success_url = 'customer_profile_view'
success_msg = u'Ваш пароль изменён на новый.'
if request.method == 'POST':
form = form_class(user=request.user, data=request.POST, prefix=form_prefix)
if form.is_valid():
new_password = form.cleaned_data['password1']
request.user.set_password(new_password)
request.user.save()
messages.add_message(request, messages.INFO, success_msg)
return redirect(success_url)
else:
form = form_class(user=request.user, prefix=form_prefix)
return render(request, template_name, {'form': form,})
@sensitive_variables()
@sensitive_post_parameters()
@login_required
@csrf_protect
def change_email(request):
form_class = forms.ChangeEmailForm
form_prefix = 'change_email'
template_name = 'myauth/change_email.html'
success_url = 'customer_profile_view'
success_msg = u'Ваш e-mail изменён на новый.'
if request.method == 'POST':
form = form_class(user=request.user, data=request.POST, prefix=form_prefix)
if form.is_valid():
new_email = form.cleaned_data['email']
request.user.email = new_email
request.user.save()
models.ConfirmEmail.objects.unconfirm(request.user)
messages.add_message(request, messages.INFO, success_msg)
return redirect(success_url)
else:
form = form_class(user=request.user, prefix=form_prefix)
return render(request, template_name, {'form': form,})
@sensitive_variables()
@sensitive_post_parameters()
@csrf_protect
def login(request):
"""Вход в систему."""
if request.session.get('login_count', None) is None:
request.session['login_count'] = 0
if request.session['login_count'] > 1:
form_class = forms.CaptchedLoginForm
else:
form_class = forms.LoginForm
#form_prefix = 'login'
form_prefix = ''
template_name = 'myauth/login.html'
success_url = 'customer_index'
if request.method == 'POST':
form = form_class(data=request.POST, prefix=form_prefix)
if form.is_valid():
auth.login(request, form.get_user())
old_session_key = request.user.profile.user_session_key
request.user.profile.user_session_key = request.session.session_key
request.user.profile.save()
del request.session['login_count']
if request.user.profile.check_name_not_filled():
success_url = 'customer_profile_edit'
return redirect(success_url)
else:
request.session['login_count'] += 1
if request.session['login_count'] > 1:
form = forms.CaptchedLoginForm(data=request.POST, prefix=form_prefix)
else:
form = form_class(prefix=form_prefix)
return render(request, template_name, {'form': form,})
def logout(request):
try:
request.user.profile.user_session_key = ''
request.user.profile.save()
except:
pass
django_logout(request)
response = redirect('/')
response.delete_cookie('close_message_license')
return response