import os import logging from uuid import uuid4 from urllib.parse import urlsplit 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 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 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})