views.py 8.33 KB
Newer Older
David Seaward's avatar
David Seaward committed
1 2
from captcha.fields import CaptchaField
from django import forms
3
from django.conf import settings
David Seaward's avatar
David Seaward committed
4
from django.contrib.auth import get_user_model
5
from django.contrib.auth import logout
6
from django.core.exceptions import ValidationError
7
from django.core.validators import RegexValidator
8 9
from django.http import HttpResponseRedirect
from django.urls import reverse
10
from django.utils import timezone
David Seaward's avatar
David Seaward committed
11
from django.utils.translation import ugettext_lazy as _
12
from registration.backends.simple.views import RegistrationView
13 14 15
from registration.forms import validators

from cart.models import ChosenReward
David Seaward's avatar
David Seaward committed
16
from ldapregister.forms import RegistrationForm
17 18
from purist.models import AccountType, get_woo_connection

19 20 21
User = get_user_model()


22
def validate_reserved_names(value):
23 24 25 26
    # premature optimization is the root of all evil
    for bad_word in settings.REG_BAD_SUBSTRINGS:
        if bad_word in value:
            raise ValidationError(validators.RESERVED_NAME, code='invalid')
27 28


29 30 31 32
def woo_email_available_validator(value):
    wc = get_woo_connection()
    result = wc.get('customers?email={}'.format(value))
    if result.ok and len(result.json()) > 0:
David Seaward's avatar
David Seaward committed
33
        raise ValidationError(_('This recovery email is already in use.'))
34 35


36
class CartRegistrationForm(RegistrationForm):
37 38 39 40 41 42 43 44 45 46 47 48
    class Meta(RegistrationForm.Meta):
        fields = (
            User.USERNAME_FIELD,
            'password1',
            'password2',
            'email'
        )

    field_order = ('username', 'email', 'password1', 'password2', 'captcha')

    email = forms.EmailField(
        label=_('Recovery email address'),
David Seaward's avatar
David Seaward committed
49
        help_text=_('Enter an email address where we can send you '
50
                    'recovery information.'),
51
        validators=[
52
            validators.validate_confusables_email, woo_email_available_validator
53
        ],
54
    )
55

56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
    password1 = forms.CharField(
        label=_("Passphrase"),
        strip=False,
        widget=forms.PasswordInput,
        help_text=_('A good passphrase is made of at least three long words.'),
        validators=[
            RegexValidator(
                regex=r'[\\\'\"]',
                message=_('\\ \' and \" are not valid characters'),
                code=None,
                inverse_match=True,
                flags=0),
        ],
    )

71 72 73 74
    def __init__(self, *args, **kwargs):
        super(CartRegistrationForm, self).__init__(*args, **kwargs)
        self.fields['username'].validators.append(validate_reserved_names)

75 76 77
    def clean_email(self):
        return self.cleaned_data['email'].lower()

78

79 80
class CartRegistrationFormWithCaptcha(CartRegistrationForm):
    captcha = CaptchaField(
81
        label=_('Please solve this math problem'),
82 83 84
        help_text=_('Prove you are not a robot. Solve this addition, subtraction or multiplication problem.'),
    )

85

86
class CartRegistrationView(RegistrationView):
87
    form_class = CartRegistrationFormWithCaptcha
88
    template_name = 'cart/registration_form.html'
89
    reward = None
90

91 92 93 94 95
    def get_form_class(self):
        if settings.DEBUG_REMOVE_CAPTCHA:
            return CartRegistrationForm
        return self.form_class

96 97 98
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['DEBUG_REGISTER_STATUS'] = settings.DEBUG_REGISTER_STATUS
99 100 101 102 103 104 105 106 107 108
        is_billing = False
        billing_carts = list(
            set().union(settings.WOO_CART_BASIC,
                        settings.WOO_CART_COMPLETE,
                        settings.WOO_CART_GROUP_BASIC,
                        settings.WOO_CART_GROUP_COMPLETE)
        )
        if self.reward in billing_carts:
            is_billing = True
        context['is_billing'] = is_billing
109 110
        return context

111
    def get(self, *args, **kwargs):
112
        logout(self.request)
113 114 115
        valid_cart_numbers = list(
            set().union(settings.WOO_CART_BASIC,
                        settings.WOO_CART_COMPLETE,
116 117
                        settings.WOO_CART_GROUP_BASIC,
                        settings.WOO_CART_GROUP_COMPLETE)
118
        )
119 120 121 122 123 124 125

        if settings.WOO_CART_ZERO:
            valid_cart_numbers.append("0")

        if settings.WOO_CART_999:
            valid_cart_numbers.append("999")

126 127 128 129 130 131
        if settings.WOO_CART_5000:
            valid_cart_numbers.append("5000")

        if settings.WOO_CART_5999:
            valid_cart_numbers.append("5999")

132
        self.reward = kwargs.get('reward', None)
133 134 135 136

        if self.reward not in valid_cart_numbers:
            return HttpResponseRedirect(reverse('register_reward', args=(settings.WOO_CART_BASIC[0],)))

137 138
        return super().get(*args, **kwargs)

139 140 141
    def post(self, *args, **kwargs):
        self.reward = kwargs.get('reward', None)
        return super().post(*args, **kwargs)
142 143

    def get_success_url(self, user):
144

145
        if self.reward in ["0", "999", "5000", "5999"]:
146 147
            # skip billing page for magic cart numbers
            # (but still force authentication for login purposes)
148

149
            url = '{}/{}/{}&reauth=1'.format(
150
                settings.WOO_URL,
151
                'wp-login.php?redirect_to=',
152 153 154 155 156
                settings.WOO_CART_THANKS_PATH,
            )

        else:
            # go to WooCommerce cart URL
157 158 159 160
            if hasattr(user, 'chosenreward'):
                user_reward = user.chosenreward.reward
            else:
                user_reward = 1
David Seaward's avatar
David Seaward committed
161
            url = '{}/{}/{}/{}&reauth=1'.format(
162
                settings.WOO_URL,
163
                'wp-login.php?redirect_to=',
164
                settings.WOO_CART_BILLING_PATH,
165
                user_reward
166 167 168
            )

        return url
169 170

    def register(self, form):
171

Birin Sanchez's avatar
Birin Sanchez committed
172
        user = super().register(form)
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
        reward = ChosenReward(user=user, reward=self.reward)
        magic_carts = ["0", "999", "5000", "5999"]
        basic_carts = list(set().union(["0", "5000"],
                                       settings.WOO_CART_BASIC,
                                       settings.WOO_CART_GROUP_BASIC))
        complete_carts = list(set().union(["999", "5999"],
                                          settings.WOO_CART_COMPLETE,
                                          settings.WOO_CART_GROUP_COMPLETE))
        group_carts = list(set().union(["5000", "5999"],
                                       settings.WOO_CART_GROUP_BASIC,
                                       settings.WOO_CART_GROUP_COMPLETE))
        is_magic = self.reward in magic_carts

        if is_magic:
            reward.is_pending = False
        # List of services that need to be activated for the new user
        to_activate = []

        if self.reward in basic_carts:
Birin Sanchez's avatar
Birin Sanchez committed
192 193
            # Register as BASIC user
            user.account_type = AccountType.BASIC
194 195 196 197 198
            if is_magic:
                reward.is_pending = False
                # Activate Chat and Social
                to_activate.append(settings.LM_SERVICES.SOCIAL)
                to_activate.append(settings.LM_SERVICES.CHAT)
199 200
                for lgroup in ['chat', 'social']:
                    user.set_ldap_group(lgroup)
201 202

        elif self.reward in complete_carts:
Birin Sanchez's avatar
Birin Sanchez committed
203 204
            # Register as COMPLETE user
            user.account_type = AccountType.COMPLETE
205 206 207 208 209 210 211 212
            if is_magic:
                reward.is_pending = False
                # Activate all but Group
                to_activate.append(settings.LM_SERVICES.SOCIAL)
                to_activate.append(settings.LM_SERVICES.CHAT)
                to_activate.append(settings.LM_SERVICES.TUNNEL)
                to_activate.append(settings.LM_SERVICES.MAIL)
                to_activate.append(settings.LM_SERVICES.XMPP)
213 214
                for lgroup in ['chat', 'social', 'mail', 'xmpp']:
                    user.set_ldap_group(lgroup)
215 216

        if self.reward in group_carts:
217
            user.account_type = AccountType.GROUP
218 219 220 221 222 223 224 225 226 227 228
            if is_magic:
                reward.is_pending = False
                # Activate Group
                to_activate.append(settings.LM_SERVICES.GROUP)

        now = timezone.now()
        next_month = now + timezone.timedelta(days=30)
        limits = user.limit_set.all()
        for limit in limits:
            if limit.service in to_activate:
                limit.renewal_date = next_month
229
                # Tunnel special case. Requires user manual activation
230
                if limit.service == settings.LM_SERVICES.TUNNEL:
231 232 233
                    limit.is_active = False
                else:
                    limit.is_active = True
234
                limit.save()
Birin Sanchez's avatar
Birin Sanchez committed
235
        user.save()
236
        reward.save()
237
        return user