"""Views to register, edit and view users and/or members including their profile.""" from datetime import date from csp.decorators import csp_update from django import http from django.conf import settings from django.contrib import auth, messages from django.contrib.auth.mixins import LoginRequiredMixin from django.urls import reverse from django.http import Http404 from django.utils.decorators import method_decorator from django.utils.translation import ugettext as _ from django.views import generic from mahjong_ranking.models import KyuDanRanking, SeasonRanking from . import forms, models RECAPTCHA_CSP = { 'SCRIPT_SRC': ( 'https://www.google.com/recaptcha/', 'https://www.gstatic.com/recaptcha/' ), 'CHILD_SRC': ('https://www.google.com/recaptcha/',) } class ActivateRegistration(generic.TemplateView): """ Activates the Registration of an User, log him in and redirect to his profile, also display an error message if the activation has failed. """ template_name = 'membership/activation_error.html' def get(self, request, *args, **kwargs): """fetch the activation key and try to activate it.""" activation_key = self.kwargs.get('activation_key') user = models.ActivationRequest.objects.activate(activation_key) if user: return self.login(user) return super(ActivateRegistration, self).get( request, *args, **kwargs) def get_context_data(self, **kwargs): """Add the acctivation days and the activation key to the template context.""" context = super(ActivateRegistration, self).get_context_data(**kwargs) context.update({ 'expiration_days': settings.ACCOUNT_ACTIVATION_DAYS, 'activation_key': self.kwargs.get('activation_key'), }) return context def login(self, user): """Log the user in and redirect to his profile.""" backend = auth.get_backends()[0] user.backend = "%s.%s" % ( backend.__module__, backend.__class__.__name__) auth.login(self.request, user) messages.success(self.request, _('Activation successful. \ You can now login anytime with you username and password.')) return http.HttpResponseRedirect( reverse('membership-edit', args=(user.username,))) class ActivationSent(generic.TemplateView): """Inform a user that a activation request has been send to him.""" template_name = 'membership/activation_sent.html' class EditMembership(LoginRequiredMixin, generic.UpdateView): """A From that allows Memebers to edit their profile.""" form_class = forms.MembershipForm def get_object(self, queryset=None): """If the authenticated user is allowed to change Membership objects, fetch the given account. Everybody else only get his own Membeship object returned.""" if self.request.user.has_perm('membership.change_membership'): return models.Membership.objects.get( username=self.kwargs['username']) else: return models.Membership.objects.get(username=self.request.user) def form_valid(self, form): """Add a success message to the message queue.""" messages.success(self.request, _('User Profile changed successfully')) return generic.UpdateView.form_valid(self, form) class MembershipDetail(LoginRequiredMixin, generic.DetailView): """To display the public user profile of an spcific user. If no user has been specified, display your own profile. """ model = models.Membership def get_object(self, queryset=None): """Get the Membership Profile matching the username given in the URI, or the current logged in user if no username has been specified. :param queryset: the `QuerySet` that will be used to look up the object. :return: a Membership Object, or raises a 404 if nothing found. """ queryset = queryset or self.get_queryset() try: if self.kwargs.get('username'): return queryset.get(username=self.kwargs['username']) elif self.request.user.is_authenticated(): return self.request.user except models.Membership.DoesNotExist: raise Http404(_("No Membership found matching the query")) def get_context_data(self, **kwargs): """ Add the ladder ranking and the Kyu and Dan ranking the user profile. :return: array with the context data """ context = generic.DetailView.get_context_data(self, **kwargs) try: context['kyu_dan_ranking'] = KyuDanRanking.objects.get( user=self.object) except KyuDanRanking.DoesNotExist: context['kyu_dan_ranking'] = None try: context['ladder_ranking'] = SeasonRanking.objects.get( user=self.object, season=date.today().year) except SeasonRanking.DoesNotExist: context['ladder_ranking'] = SeasonRanking(user=self.object) return context class RegisterForm(generic.FormView): """To register a new user on this website. Secured by reCaptcha.""" form_class = forms.RegistrationForm success_url = '/membership/activation_sent/' template_name = 'membership/register_form.html' @method_decorator(csp_update(**RECAPTCHA_CSP)) def dispatch(self, request, *args, **kwargs): """Overwrite to add googles recaptcha ressoruces to the Content-Security_Policity HTTP Headers. :param request: :param args: :param kwargs: :return: """ return super(RegisterForm, self).dispatch(request, *args, **kwargs) def form_valid(self, form): """Save the formdata and redirect to the success_url. """ form.save() return generic.FormView.form_valid(self, form)