Mark__C
Mark__C

Reputation: 825

How to get a token passed to Django allauth Signup

I am using allauth and want a user to be able to invite people via email to sign up to an account. When the new user signs up, I want to set their 'school' field to be the same as the user who invited them. In other words, they are part of the same school and I want to store that info when saving the new user.

To achieve this, I have an invite button which sends an email with the original user's school passed as a token, like so:

class AddUsers(TemplateView):
    template_name = 'schools/add-users.html'

    def get(self, request, *args, **kwargs):

        add_user_form = AddUserForm()

        context = {
            'add_user_form': add_user_form
        }

        return render(request, self.template_name, context)

    def post(self, request, *args, **kwargs):

        if 'add_users' in request.POST:

            add_user_form = AddUserForm(request.POST)
            if add_user_form.is_valid():
                to_email_address = add_user_form.cleaned_data.get('email_field')
                user = request.user
                school = request.user.school

                mail_subject = 'Invitation to create an account'

                url = request.build_absolute_uri(reverse('account_signup'))
                uid = urlsafe_base64_encode(force_bytes(school.pk))
                token = account_activation_token.make_token(school)
                activation_link = "{0}?uid={1}&token{2}".format(url, uid, token)

                message = 'Hi,\n\nYour colleague ' + user.first_name + ' has invited you to sign up.\n\n'
                message += 'Click the activation link below\n\n'
                message += activation_link

                email = EmailMessage(mail_subject, message, to=[to_email_address])
                email.send()

                return HttpResponseRedirect(reverse('schools:add-users',))

        return HttpResponseRedirect(reverse('settings', ))

I override the allauth Signup form like this for a regular new user, but when the user has been invited by another user (i.e. via the email activation link with the school token), I plan to hide the school field and save the object held in the token value instead:

class SignupForm(ModelForm):
    first_name = forms.CharField(max_length=30)
    last_name = forms.CharField(max_length=150)

    class Meta:
        model = School

        fields = ['school_name', 'authority']

    def __init__(self, *args, **kwargs):
        super(SignupForm, self).__init__(*args, **kwargs)
        self.fields['first_name'].widget.attrs['class'] = 'form-control'
        self.fields['first_name'].widget.attrs['placeholder'] = 'First name'

        self.fields['last_name'].widget.attrs['class'] = 'form-control'
        self.fields['last_name'].widget.attrs['placeholder'] = 'Last name'

        self.fields['school_name'].widget.attrs['class'] = 'form-control'
        self.fields['school_name'].widget.attrs['placeholder'] = 'School name'

        self.fields['authority'].queryset = Authority.objects.get_all_authorities()
        self.fields['authority'].label = 'Local authority'
        self.fields['authority'].widget.attrs['class'] = 'form-control'
        self.fields['authority'].empty_label = 'No local authority'

    def signup(self, request, user):

        school_name = self.cleaned_data['school_name']
        first_name = self.cleaned_data['first_name']
        last_name = self.cleaned_data['last_name']
        authority = self.cleaned_data['authority']
        school = School.objects.new_school_account(school_name, authority, 28)
        user.school = school
        user.first_name = first_name
        user.last_name = last_name
        user.save()

This works and sends an email with the token which correctly redirects to the allauth account_signup page. I can see how I can use the code in this solution to convert the token back again, but I don't know how/where I can actually access the token using allauth Signup in order to save the school when saving the new user details.

So my question is - I am passing a token to the allauth account_signup page but how can I get the token so I can process it?

Upvotes: 0

Views: 917

Answers (1)

Gijsriet
Gijsriet

Reputation: 163

token = request.GET.get('token')

You can get it in de dispatch method in the SignupView like this:

class MySignupView(SignupView):
    def dispatch(self, request, *args, **kwargs):
        token = request.GET.get('token')
        return super(MySignupView, self).dispatch(request, *args, **kwargs)

Upvotes: 2

Related Questions