adapter.py 5.01 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
from allauth.account.adapter import get_adapter as get_account_adapter
9
10
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter
from allauth.socialaccount.views import ConnectionsView
11
from allauth.exceptions import ImmediateHttpResponse
12
from braces.views import LoginRequiredMixin
13

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

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

18
19
20
21
22
23
    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.
    """
24

25
26
    # 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
27
28
    # def pre_social_login(self, request, sociallogin):
    #     print(request.get_full_path(), 'pre_login')
29

30
    def populate_user(self, request, sociallogin, data):
31
32
33
        # 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.
34
35
36
37
38
        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
39
        assert request.user.is_authenticated()
40

41
42
        # 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
43
44
45
46
        if not request.user.student.completedSocial:
            return reverse('welcomeSocial', kwargs={
                'slug': request.user.username,
            })
47
        else:
48
            return reverse('update_student', kwargs={
49
                'slug': request.user.username,
50
51
52
53
            })

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

        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."""
60

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

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

77
class RemoveSocialConfirmationView(LoginRequiredMixin, ConnectionsView):
78
79
80
81
    """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."""

82
    template_name = "social/remove_social.html"
83
84
85
86
87
    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!
88
            return HttpResponseRedirect(reverse('update_student',
Daniel W Bond's avatar
pep8 me    
Daniel W Bond committed
89
                                        kwargs={'slug': self.request.user.username}))
90
91
92
93
        else:
            return super(RemoveSocialConfirmationView, self).get(request, *args, **kwargs)

    def form_valid(self, form):
94
95
96
97
98
99
100
        # copied directly, except using SUCCESS rather than INFO
        get_account_adapter().add_message(self.request,
                                          messages.SUCCESS,
                                          'socialaccount/messages/'
                                          'account_disconnected.txt')
        form.save()
        return HttpResponseRedirect(self.get_success_url())
101
102

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