adapter.py 4.62 KB
Newer Older
1
# standard library imports
2
from __future__ import absolute_import, print_function
Daniel W Bond's avatar
Daniel W Bond committed
3
# core django imports
4
from django.core.urlresolvers import reverse
5
6
from django.contrib import messages
from django.http import HttpResponseRedirect
7
# third party imports
8
9
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter
from allauth.socialaccount.views import ConnectionsView
10
from allauth.exceptions import ImmediateHttpResponse
11
from braces.views import LoginRequiredMixin
12

Daniel W Bond's avatar
pep8 me    
Daniel W Bond committed
13

14
class AccountAdapter(DefaultSocialAccountAdapter):
15
    """A custom implementation of a portion of the allauth social media package.
16

17
18
19
20
21
22
    We're overriding a number of aspects of the allauth account adapter to support
    our special use of the package. We are using CAS, not Django's built-in
    authentication. Accordingly we change the where directed when successfully
    connecting an account and how errors are dealt with. Additionally, we are not using
    the social media accounts to verify or overwrite any aspect of the User model.
    """
23

24
25
    # the request processed by the adapter is one from the successful oauth callback
    # uncomment this method to print what URL you are arriving from
Daniel W Bond's avatar
pep8 me    
Daniel W Bond committed
26
27
    # def pre_social_login(self, request, sociallogin):
    #     print(request.get_full_path(), 'pre_login')
28

29
    def populate_user(self, request, sociallogin, data):
30
31
32
        # This is a hook to populate User attributes, but we expressly don't actually
        # want to overwrite anything from the social media account user. It's intended
        # in the package for when you are using social media for login.
33
34
35
36
37
        user = sociallogin.user
        return user

    def get_connect_redirect_url(self, request, socialaccount):
        # where the user is sent if the social account is indeed authenticated
38
        assert request.user.is_authenticated()
39

40
41
        # we are approximating that if a user has not completed the welcome walkthough,
        # it is likely the page on which they started-- see the pre_social_login method
42
43
44
45
        if not request.user.student.completedSocial:
            return reverse('welcomeSocial', kwargs={
                'slug': request.user.username,
            })
46
        else:
47
            return reverse('update_student', kwargs={
48
                'slug': request.user.username,
49
50
51
52
            })

    def authentication_error(self, request, provider_id, error=None, exception=None,
                             extra_context=None):
53
        """Adds a custom message to the message queue if social media auth fails."""
54
55
56
57
58

        error_message = """Looks like something went awry with your social
                           authentication. Wait a moment and try your username and
                           password again. If things are still broken, let us know by
                           sending an email to roomlist@lists.srct.gmu.edu."""
59

60
        if not request.user.student.completedSocial:
61
62
            # as a reminder, here is how django handles messages
            # https://docs.djangoproject.com/en/1.8/ref/contrib/messages/
63
64
65
66
67
68
69
            messages.add_message(request, messages.ERROR, error_message)
            social_redirect = HttpResponseRedirect(reverse('welcomeSocial', kwargs={
                                  'slug': request.user.username,
                              }))
            raise ImmediateHttpResponse(social_redirect)
        else:
            messages.add_message(request, messages.ERROR, error_message)
70
            update_redirect =  HttpResponseRedirect(reverse('update_student', kwargs={
71
                                  'slug': request.user.username,
Daniel W Bond's avatar
pep8 me    
Daniel W Bond committed
72
                               }))
73
            raise ImmediateHttpResponse(update_redirect)
74

Daniel W Bond's avatar
pep8 me    
Daniel W Bond committed
75

76
class RemoveSocialConfirmationView(LoginRequiredMixin, ConnectionsView):
77
78
79
80
    """To customize where users are sent when removing their social media connections.
    We have written our own template to handle this feature that is much prettier than
    the one provided by allauth."""

81
82
83
84
85
86
    template_name = "remove_social.html"
    login_url = 'login'

    def get(self, request, *args, **kwargs):
        if not request.user.socialaccount_set.all():
            # no social media accounts? back to the settings page with you!
87
            return HttpResponseRedirect(reverse('update_student',
Daniel W Bond's avatar
pep8 me    
Daniel W Bond committed
88
                                        kwargs={'slug': self.request.user.username}))
89
90
91
92
93
94
95
        else:
            return super(RemoveSocialConfirmationView, self).get(request, *args, **kwargs)

    def form_valid(self, form):
        return super(RemoveSocialConfirmationView, self).form_valid(form)

    def get_success_url(self):
96
        return reverse('update_student',
Daniel W Bond's avatar
pep8 me    
Daniel W Bond committed
97
                        kwargs={'slug': self.request.user.username})