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.
283 lines
11 KiB
283 lines
11 KiB
import string
|
|
|
|
import os
|
|
import logging
|
|
from uuid import uuid4
|
|
from urllib.parse import urlsplit, urlencode
|
|
|
|
from django.db.models import Q
|
|
from facepy import GraphAPI
|
|
from facepy.exceptions import FacepyError
|
|
from django.contrib.auth import get_user_model, logout, login, views
|
|
from django.contrib.auth.forms import AuthenticationForm
|
|
from django.core.files.base import ContentFile
|
|
from django.http import JsonResponse, HttpResponse
|
|
from django.urls import reverse_lazy
|
|
from django.utils.decorators import method_decorator
|
|
from django.views.decorators.csrf import csrf_exempt
|
|
from django.views.generic import FormView, View, TemplateView
|
|
from django.shortcuts import redirect
|
|
from django.conf import settings
|
|
|
|
from apps.notification.utils import send_email
|
|
from apps.config.models import Config
|
|
from apps.user.models import Referral
|
|
from .forms import LearnerRegistrationForm, LandingRegistrationForm
|
|
from .tokens import verification_email_token
|
|
|
|
|
|
User = get_user_model()
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class LearnerRegistrationView(FormView):
|
|
form_class = LearnerRegistrationForm
|
|
template_name = "auth/registration-learner.html"
|
|
success_url = '/'
|
|
|
|
def form_valid(self, form):
|
|
config = Config.load()
|
|
first_name = form.cleaned_data['first_name']
|
|
last_name = form.cleaned_data['last_name']
|
|
email = form.cleaned_data['email'].lower()
|
|
password = form.cleaned_data['password']
|
|
|
|
user, created = User.objects.get_or_create(
|
|
email=email,
|
|
)
|
|
|
|
if not created:
|
|
if self.request.is_ajax():
|
|
return JsonResponse({
|
|
"success": False,
|
|
'errors': {'__all__': [{'message': 'Возможно вы уже зарегистрированы?'}]}
|
|
}, status=400)
|
|
else:
|
|
context = self.get_context_data(form=form)
|
|
context['error'] = 'Возможно вы уже зарегистрированы?'
|
|
return self.render_to_response(context)
|
|
|
|
user.username = email
|
|
user.first_name = first_name
|
|
user.last_name = last_name
|
|
|
|
user.set_password(password)
|
|
user.save()
|
|
referrer = self.request.session.get('referrer')
|
|
if referrer:
|
|
Referral.objects.create(referral=user, referrer_id=referrer, bonus=config.REFERRAL_BONUS,
|
|
referrer_bonus=config.REFERRER_BONUS)
|
|
# TODO: email admins? мб реферера уже нет, старая ссылка
|
|
self.request.session['referrer'] = None
|
|
login(self.request, user)
|
|
|
|
# fixme: change email text
|
|
# fixme: async send email
|
|
http_referer = urlsplit(self.request.META.get('HTTP_REFERER'))
|
|
http_referer = str(http_referer[0]) + '://' + str(http_referer[1])
|
|
token = verification_email_token.make_token(user)
|
|
url = http_referer + str(reverse_lazy('lilcity:verification-email', args=[token, user.id]))
|
|
try:
|
|
send_email('Вы успешно прошли регистрацию', email, "notification/email/verification_email.html", url=url, config=config)
|
|
except Exception as e:
|
|
logger.error(str(e))
|
|
|
|
if self.request.is_ajax():
|
|
return JsonResponse({"success": True}, status=201)
|
|
else:
|
|
return super().form_valid(form)
|
|
|
|
def form_invalid(self, form):
|
|
if self.request.is_ajax():
|
|
return JsonResponse(form.errors.get_json_data(escape_html=True), status=400)
|
|
else:
|
|
return super().form_invalid(form)
|
|
|
|
|
|
class LogoutView(View):
|
|
def get(self, request, *args, **kwargs):
|
|
logout(request)
|
|
return redirect('/')
|
|
|
|
|
|
class LoginView(FormView):
|
|
form_class = AuthenticationForm
|
|
template_name = "auth/login.html"
|
|
success_url = '/'
|
|
|
|
def form_valid(self, form):
|
|
login(self.request, form.get_user())
|
|
self.request.session['referrer'] = None
|
|
if self.request.is_ajax():
|
|
return JsonResponse({"success": True})
|
|
else:
|
|
return super().form_valid(form)
|
|
|
|
def form_invalid(self, form):
|
|
if self.request.is_ajax():
|
|
return JsonResponse({"success": False, "errors": form.errors.get_json_data(escape_html=True)}, status=400)
|
|
else:
|
|
return super().form_invalid(form)
|
|
|
|
|
|
class VerificationEmailView(View):
|
|
def get(self, request, *args, **kwargs):
|
|
user = User.objects.get(pk=kwargs.get('uid'))
|
|
is_valid_token = verification_email_token.check_token(
|
|
user, kwargs.get('token'))
|
|
next = request.GET.get('next')
|
|
|
|
if is_valid_token:
|
|
user.is_email_proved = True
|
|
user.save()
|
|
login(request, user)
|
|
self.request.session['referrer'] = None
|
|
return redirect(next or reverse_lazy('lilcity:success-verification-email'))
|
|
else:
|
|
return JsonResponse({"success": False}, status=400)
|
|
|
|
|
|
class SuccessVerificationEmailView(TemplateView):
|
|
template_name = 'auth/success-verification.html'
|
|
|
|
|
|
class PasswordResetView(views.PasswordContextMixin, FormView):
|
|
email_template_name = 'auth/password_reset_email.txt'
|
|
subject_template_name = "auth/password_reset_subject.txt"
|
|
form_class = views.PasswordResetForm
|
|
template_name = "auth/password_reset.html"
|
|
success_url = '/'
|
|
|
|
extra_email_context = None
|
|
from_email = None
|
|
html_email_template_name = "auth/password_reset_email.html"
|
|
title = 'Password reset'
|
|
token_generator = views.default_token_generator
|
|
|
|
def form_valid(self, form):
|
|
config = Config.load()
|
|
extra_email_context = {'config': config}
|
|
if self.extra_email_context and isinstance(self.extra_email_context, dict):
|
|
extra_email_context.update(self.extra_email_context)
|
|
opts = {
|
|
'domain_override': 'https://' + settings.MAIN_HOST,
|
|
'use_https': self.request.is_secure(),
|
|
'token_generator': self.token_generator,
|
|
'from_email': self.from_email,
|
|
'email_template_name': self.email_template_name,
|
|
'subject_template_name': self.subject_template_name,
|
|
'request': self.request,
|
|
'html_email_template_name': self.html_email_template_name,
|
|
'extra_email_context': extra_email_context,
|
|
}
|
|
form.save(**opts)
|
|
if self.request.is_ajax():
|
|
return JsonResponse({"success": True})
|
|
else:
|
|
return super().form_valid(form)
|
|
|
|
|
|
class PasswordResetConfirmView(views.PasswordResetConfirmView):
|
|
template_name = "auth/password_reset_confirm.html"
|
|
success_url = reverse_lazy('lilcity:password_reset_complete')
|
|
|
|
|
|
class PasswordResetComplete(views.PasswordResetCompleteView):
|
|
template_name = 'auth/password_reset_complete.html'
|
|
|
|
|
|
@method_decorator(csrf_exempt, name="dispatch")
|
|
class FacebookLoginOrRegistration(View):
|
|
def post(self, requests, *args, **kwargs):
|
|
access_token = requests.POST.get('access_token')
|
|
graph = GraphAPI(access_token)
|
|
try:
|
|
data = graph.get('/me?fields=email, first_name, last_name')
|
|
photo_data = graph.get('/me/picture?height=120')
|
|
except FacepyError:
|
|
return JsonResponse({"success": False})
|
|
|
|
fb_id = data.get('id')
|
|
|
|
try:
|
|
user = User.objects.get(fb_id=fb_id)
|
|
except User.DoesNotExist:
|
|
email = requests.POST.get('email') or data.get('email')
|
|
if not email:
|
|
return JsonResponse({"success": False,
|
|
"errors": {"email": 'is field required'}
|
|
})
|
|
else:
|
|
email = email.lower()
|
|
try:
|
|
user = User.objects.get(email__iexact=email)
|
|
except User.DoesNotExist:
|
|
first_name = data.get('first_name', '')
|
|
last_name = data.get('last_name', '')
|
|
|
|
user = User.objects.create_user(username=email, email=email, first_name=first_name, last_name=last_name, password=uuid4().hex)
|
|
user.is_email_proved = True
|
|
user.fb_id = fb_id
|
|
if photo_data:
|
|
photo = ContentFile(photo_data)
|
|
fname = str(fb_id) + '.jpg'
|
|
user.photo.save(fname, photo, save=True)
|
|
user.save()
|
|
|
|
referrer = self.request.session.get('referrer')
|
|
if referrer:
|
|
config = Config.load()
|
|
Referral.objects.create(referral=user, referrer_id=referrer, bonus=config.REFERRAL_BONUS,
|
|
referrer_bonus=config.REFERRER_BONUS)
|
|
# TODO: email admins? мб реферера уже нет, старая ссылка
|
|
self.request.session['referrer'] = None
|
|
|
|
login(requests, user=user)
|
|
return JsonResponse({"success": True})
|
|
else:
|
|
if (not user.photo or (user.photo and not os.path.isfile(user.photo.path))) and photo_data:
|
|
photo = ContentFile(photo_data)
|
|
fname = str(fb_id) + '.jpg'
|
|
user.photo.save(fname, photo, save=True)
|
|
login(requests, user=user)
|
|
self.request.session['referrer'] = None
|
|
return JsonResponse({"success": True})
|
|
|
|
|
|
class LandingRegistrationView(View):
|
|
|
|
def post(self, request, *args, **kwargs):
|
|
form = LandingRegistrationForm(request.POST)
|
|
if not form.is_valid():
|
|
return HttpResponse(form.errors.as_text())
|
|
phone = form.cleaned_data['phone']
|
|
name = form.cleaned_data['name'].split()
|
|
email = form.cleaned_data['email'].lower()
|
|
|
|
if User.objects.filter(Q(email=email) | Q(phone=phone)).count():
|
|
return redirect('/p/user-exists')
|
|
|
|
user = User(
|
|
username=email,
|
|
email=email,
|
|
phone=phone,
|
|
)
|
|
user.first_name = name[0]
|
|
if len(name) > 1:
|
|
user.last_name = name[1]
|
|
password = User.objects.make_random_password(8, string.ascii_lowercase + string.digits)
|
|
user.set_password(password)
|
|
user.save()
|
|
|
|
verification_token = verification_email_token.make_token(user)
|
|
url = 'https://%s%s?%s' % (settings.MAIN_HOST,
|
|
reverse_lazy('lilcity:verification-email', args=[verification_token, user.id]),
|
|
urlencode({'next': 'https://lil.school/p/free-lesson'}))
|
|
try:
|
|
send_email('Регистрация в Lil School', email, "notification/email/landing_registration.html", url=url,
|
|
user=user, password=password)
|
|
except Exception as e:
|
|
logger.error(str(e))
|
|
|
|
return redirect(url)
|
|
|
|
|