Exemple #1
0
    def test_pre_social_login_matched_login(self):
        """
        When we detected a legacy Persona account, advise recovery of account.

        A user tries to sign in with GitHub, but their GitHub email matches
        an existing MDN account backed by Persona. They are prompted to
        recover the existing account.

        https://bugzil.la/1063830, happy path
        """
        # Set up a session-only GitHub SocialLogin
        # These are created at the start of the signup process, and saved on
        #  profile completion.
        github_account = SocialAccount.objects.get(user__username='******')
        github_login = SocialLogin(account=github_account,
                                   user=github_account.user)

        # Setup existing Persona SocialLogin for the same email
        SocialAccount.objects.create(user=github_account.user,
                                     provider='persona',
                                     uid=github_account.user.email)

        request = self.rf.get('/')
        session = self.client.session
        session['sociallogin_provider'] = 'github'
        session['socialaccount_sociallogin'] = github_login.serialize()
        session.save()
        request.session = session

        # Verify the social_login receiver over-writes the provider
        # stored in the session
        self.adapter.pre_social_login(request, github_login)
        session = request.session
        eq_(session['sociallogin_provider'], 'github')
Exemple #2
0
def login(request):
    if 'openid' in request.GET or request.method == 'POST':
        form = LoginForm(request.REQUEST)
        if form.is_valid():
            client = _openid_consumer(request)
            try:
                auth_request = client.begin(form.cleaned_data['openid'])
                if QUERY_EMAIL:
                    sreg = SRegRequest()
                    sreg.requestField(field_name=SRegField.EMAIL,
                                      required=True)
                    auth_request.addExtension(sreg)
                    ax = FetchRequest()
                    ax.add(AttrInfo(AXAttribute.CONTACT_EMAIL,
                                    required=True))
                    auth_request.addExtension(ax)
                callback_url = reverse(callback)
                SocialLogin.stash_state(request)
                redirect_url = auth_request.redirectURL(
                    request.build_absolute_uri('/'),
                    request.build_absolute_uri(callback_url))
                return HttpResponseRedirect(redirect_url)
            # UnicodeDecodeError:
            # see https://github.com/necaris/python3-openid/issues/1
            except (UnicodeDecodeError, DiscoveryFailure) as e:
                if request.method == 'POST':
                    form._errors["openid"] = form.error_class([e])
                else:
                    return render_authentication_error(request)
    else:
        form = LoginForm()
    d = dict(form=form)
    return render_to_response('openid/login.html',
                              d, context_instance=RequestContext(request))
Exemple #3
0
def persona_login(request):
    assertion = request.POST.get('assertion', '')
    audience = request.build_absolute_uri('/')
    resp = requests.post('https://verifier.login.persona.org/verify', {
        'assertion': assertion,
        'audience': audience
    })
    if resp.json['status'] != 'okay':
        return render_authentication_error(request)
    email = resp.json['email']
    user = User(email=email)
    extra_data = resp.json
    account = SocialAccount(uid=email,
                            provider=PersonaProvider.id,
                            extra_data=extra_data,
                            user=user)
    # TBD: Persona e-mail addresses are verified, so we could check if
    # a matching local user account already exists with an identical
    # verified e-mail address and short-circuit the social login. Then
    # again, this holds for all social providers that guarantee
    # verified e-mail addresses, so if at all, short-circuiting should
    # probably not be handled here...
    login = SocialLogin(account)
    login.state = SocialLogin.state_from_request(request)
    return complete_social_login(request, login)
Exemple #4
0
    def test_pre_social_login_matched_google_login(self):
        """
        When we detected a legacy Persona account, advise recovery of account.

        A user tries to sign in with Google, but their Google email matches
        an existing MDN account backed by Persona. They are prompted to
        recover the existing account.

        Same as above, but with Google instead of GitHub
        """
        # Set up a session-only Google SocialLogin
        # These are created at the start of the signup process, and saved on
        #  profile completion.
        google_account = SocialAccount.objects.get(user__username='******')
        google_login = SocialLogin(account=google_account,
                                   user=google_account.user)

        # Setup existing Persona SocialLogin for the same email
        SocialAccount.objects.create(user=google_account.user,
                                     provider='persona',
                                     uid=google_account.user.email)

        request = self.rf.get('/')
        session = self.client.session
        session['sociallogin_provider'] = 'google'
        session['socialaccount_sociallogin'] = google_login.serialize()
        session.save()
        request.session = session

        # Verify the social_login receiver over-writes the provider
        # stored in the session
        self.adapter.pre_social_login(request, google_login)
        session = request.session
        assert 'google' == session['sociallogin_provider']
Exemple #5
0
    def test_pre_social_login_error_for_unmatched_login(self):
        """ https://bugzil.la/1063830 """

        # Set up a GitHub SocialLogin in the session
        github_account = SocialAccount.objects.get(user__username='******')
        github_login = SocialLogin(account=github_account)

        request = RequestFactory().get('/')
        session = self.client.session
        session['socialaccount_sociallogin'] = github_login.serialize()
        session.save()
        request.session = session

        # django 1.4 RequestFactory requests can't be used to test views that
        # call messages.add (https://code.djangoproject.com/ticket/17971)
        # FIXME: HACK from http://stackoverflow.com/q/11938164/571420
        messages = FallbackStorage(request)
        request._messages = messages

        # Set up an un-matching Persona SocialLogin for request
        persona_account = SocialAccount(user=User(),
                                        provider='persona',
                                        uid='*****@*****.**')
        persona_login = SocialLogin(account=persona_account)

        assert_raises(ImmediateHttpResponse, self.adapter.pre_social_login,
                      request, persona_login)
        for m in messages:
            eq_(django_messages.ERROR, m.level)
Exemple #6
0
    def perform_openid_auth(self, form):
        if not form.is_valid():
            return form

        request = self.request
        provider = self.provider(request)
        endpoint = form.cleaned_data["openid"]
        client = self.get_client(provider, endpoint)
        realm = self.get_realm(provider)

        auth_request = client.begin(endpoint)
        if QUERY_EMAIL:
            sreg = SRegRequest()
            for name in SRegFields:
                sreg.requestField(field_name=name, required=True)
            auth_request.addExtension(sreg)
            ax = FetchRequest()
            for name in AXAttributes:
                ax.add(AttrInfo(name, required=True))
            provider = OpenIDProvider(request)
            server_settings = provider.get_server_settings(
                request.GET.get("openid"))
            extra_attributes = server_settings.get("extra_attributes", [])
            for _, name, required in extra_attributes:
                ax.add(AttrInfo(name, required=required))
            auth_request.addExtension(ax)

        SocialLogin.stash_state(request)

        # Fix for issues 1523 and 2072 (github django-allauth)
        if "next" in form.cleaned_data and form.cleaned_data["next"]:
            auth_request.return_to_args["next"] = form.cleaned_data["next"]
        redirect_url = auth_request.redirectURL(
            realm, request.build_absolute_uri(self.get_callback_url()))
        return HttpResponseRedirect(redirect_url)
Exemple #7
0
    def test_pre_social_login_error_for_unmatched_login(self):
        """ https://bugzil.la/1063830 """

        # Set up a GitHub SocialLogin in the session
        github_account = SocialAccount.objects.get(user__username='******')
        github_login = SocialLogin(account=github_account)

        request = RequestFactory().get('/')
        session = self.client.session
        session['socialaccount_sociallogin'] = github_login.serialize()
        session.save()
        request.session = session

        # django 1.4 RequestFactory requests can't be used to test views that
        # call messages.add (https://code.djangoproject.com/ticket/17971)
        # FIXME: HACK from http://stackoverflow.com/q/11938164/571420
        messages = FallbackStorage(request)
        request._messages = messages

        # Set up an un-matching Persona SocialLogin for request
        persona_account = SocialAccount(user=User(), provider='persona',
                                        uid='*****@*****.**')
        persona_login = SocialLogin(account=persona_account)

        assert_raises(ImmediateHttpResponse,
                      self.adapter.pre_social_login, request, persona_login)
        for m in messages:
            eq_(django_messages.ERROR, m.level)
Exemple #8
0
def login(request):
    if 'openid' in request.GET or request.method == 'POST':
        form = LoginForm(request.REQUEST)
        if form.is_valid():
            client = _openid_consumer(request)
            try:
                auth_request = client.begin(form.cleaned_data['openid'])
                if QUERY_EMAIL:
                    sreg = SRegRequest()
                    sreg.requestField(field_name=SRegField.EMAIL,
                                      required=True)
                    auth_request.addExtension(sreg)
                    ax = FetchRequest()
                    ax.add(AttrInfo(AXAttribute.CONTACT_EMAIL, required=True))
                    auth_request.addExtension(ax)
                callback_url = reverse(callback)
                SocialLogin.stash_state(request)
                redirect_url = auth_request.redirectURL(
                    request.build_absolute_uri('/'),
                    request.build_absolute_uri(callback_url))
                return HttpResponseRedirect(redirect_url)
            # UnicodeDecodeError: see https://github.com/necaris/python3-openid/issues/1
            except (UnicodeDecodeError, DiscoveryFailure) as e:
                if request.method == 'POST':
                    form._errors["openid"] = form.error_class([e])
                else:
                    return render_authentication_error(request)
    else:
        form = LoginForm()
    d = dict(form=form)
    return render_to_response('openid/login.html',
                              d,
                              context_instance=RequestContext(request))
Exemple #9
0
    def test_pre_social_login_banned_user(self):
        """A banned user is not allowed to login."""
        # Set up a GitHub SocialLogin in the session
        github_account = SocialAccount.objects.get(user__username='******')
        github_login = SocialLogin(account=github_account,
                                   user=github_account.user)

        request = self.rf.get('/')
        session = self.client.session
        session['sociallogin_provider'] = 'github'
        session['socialaccount_sociallogin'] = github_login.serialize()
        session.save()
        request.session = session
        request.user = AnonymousUser()
        request.LANGUAGE_CODE = 'en-US'

        # Ban the user
        banned_by = User.objects.get(username='******')
        UserBan.objects.create(user=github_account.user,
                               by=banned_by,
                               reason='Banned by unit test.')

        with pytest.raises(ImmediateHttpResponse) as e_info:
            self.adapter.pre_social_login(request, github_login)
        resp = e_info.value.response
        assert 'Banned by unit test.' in resp.content
        assert not resp.has_header('Vary')
        never_cache = 'no-cache, no-store, must-revalidate, max-age=0'
        assert resp['Cache-Control'] == never_cache
 def test_create(self, fb_mock, get_mock):
     user = User(username="******")
     login = SocialLogin(user=user, account=SocialAccount())
     login.state["next"] = "/"
     fb_mock.return_value = login
     ret_mock = MagicMock()
     ret_mock.json.return_value = { "access_token": "OK" }
     get_mock.return_value = ret_mock
     factory = APIRequestFactory()
     request = factory.post(
         "/",
         { "access_token": "1234" },
         format="json"
     )
     request.session = SessionStore()
     self.app.sites.add(get_current_site(request))
     response = FacebookLoginView.as_view()(request)
     self.assertEqual(response.status_code, 200)
     code = response.data["key"]
     user = Token.objects.get(key=code).user
     self.assertIsNotNone(user.socialaccount_set.first())
     self.assertEqual(
         user.socialaccount_set.first().socialtoken_set.first().token,
         "OK"
     )
Exemple #11
0
def persona_login(request):
    assertion = request.POST.get('assertion', '')
    audience = request.build_absolute_uri('/')
    resp = requests.post('https://verifier.login.persona.org/verify',
                         {'assertion': assertion,
                          'audience': audience})
    if resp.json()['status'] != 'okay':
        return render_authentication_error(request)
    email = resp.json()['email']
    user = get_adapter() \
        .populate_new_user(email=email)
    extra_data = resp.json()
    account = SocialAccount(uid=email,
                            provider=PersonaProvider.id,
                            extra_data=extra_data,
                            user=user)
    # TBD: Persona e-mail addresses are verified, so we could check if
    # a matching local user account already exists with an identical
    # verified e-mail address and short-circuit the social login. Then
    # again, this holds for all social providers that guarantee
    # verified e-mail addresses, so if at all, short-circuiting should
    # probably not be handled here...
    login = SocialLogin(account)
    login.state = SocialLogin.state_from_request(request)
    return complete_social_login(request, login)
Exemple #12
0
    def test_pre_social_login_banned_user(self):
        """A banned user is not allowed to login."""
        # Set up a GitHub SocialLogin in the session
        github_account = SocialAccount.objects.get(user__username='******')
        github_login = SocialLogin(account=github_account,
                                   user=github_account.user)

        request = self.rf.get('/')
        session = self.client.session
        session['sociallogin_provider'] = 'github'
        session['socialaccount_sociallogin'] = github_login.serialize()
        session.save()
        request.session = session
        request.user = AnonymousUser()
        request.LANGUAGE_CODE = 'en-US'

        # Ban the user
        banned_by = User.objects.get(username='******')
        UserBan.objects.create(user=github_account.user, by=banned_by,
                               reason='Banned by unit test.')

        with pytest.raises(ImmediateHttpResponse) as e_info:
            self.adapter.pre_social_login(request, github_login)
        resp = e_info.value.response
        assert 'Banned by unit test.' in resp.content
        assert not resp.has_header('Vary')
        never_cache = 'no-cache, no-store, must-revalidate, max-age=0'
        assert resp['Cache-Control'] == never_cache
Exemple #13
0
 def post(self, request, *args, **kwargs):
     data = dict(list(request.GET.items()) + list(request.POST.items()))
     if self.provider.endpoint:
         data['openid'] = self.provider.endpoint
     form = LoginForm(data)
     if form.is_valid():
         client = _openid_consumer(request)
         try:
             auth_request = client.begin(form.cleaned_data['openid'])
             if QUERY_EMAIL:
                 sreg = SRegRequest()
                 for name in SRegFields:
                     sreg.requestField(field_name=name, required=True)
                 auth_request.addExtension(sreg)
                 ax = FetchRequest()
                 for name in AXAttributes:
                     ax.add(AttrInfo(name, required=True))
                 auth_request.addExtension(ax)
             callback_url = reverse(self.callback_view)
             SocialLogin.stash_state(request)
             redirect_url = auth_request.redirectURL(
                 request.build_absolute_uri('/'),
                 request.build_absolute_uri(callback_url))
             return HttpResponseRedirect(redirect_url)
         # UnicodeDecodeError:
         # see https://github.com/necaris/python3-openid/issues/1
         except (UnicodeDecodeError, DiscoveryFailure) as e:
             if request.method == 'POST':
                 form._errors["openid"] = form.error_class([e])
             else:
                 return render_authentication_error(request,
                                                    self.provider.id,
                                                    exception=e)
     return render(request, self.template_name, {'form': form})
Exemple #14
0
    def test_pre_social_login_error_for_unmatched_login(self):
        """ https://bugzil.la/1063830 """

        # Set up a GitHub SocialLogin in the session
        github_account = SocialAccount.objects.get(user__username='******')
        github_login = SocialLogin(account=github_account,
                                   user=github_account.user)

        request = self.rf.get('/')
        session = self.client.session
        session['socialaccount_sociallogin'] = github_login.serialize()
        session.save()
        request.session = session
        messages = self.get_messages(request)

        # Set up an un-matching Persona SocialLogin for request
        persona_account = SocialAccount(user=self.user_model(),
                                        provider='persona',
                                        uid='*****@*****.**')
        persona_login = SocialLogin(account=persona_account)

        self.assertRaises(ImmediateHttpResponse,
                          self.adapter.pre_social_login, request, persona_login)
        queued_messages = list(messages)
        eq_(len(queued_messages), 1)
        eq_(django_messages.ERROR, queued_messages[0].level)
Exemple #15
0
    def test_pre_social_login_matched_login(self):
        """
        https://bugzil.la/1063830, happy path

        A user tries to sign in with GitHub, but their GitHub email matches
        an existing Persona-backed MDN account. They follow the prompt to login
        with Persona, and the accounts are connected.
        """

        # Set up a GitHub SocialLogin in the session
        github_account = SocialAccount.objects.get(user__username='******')
        github_login = SocialLogin(account=github_account,
                                   user=github_account.user)

        request = self.rf.get('/')
        session = self.client.session
        session['sociallogin_provider'] = 'github'
        session['socialaccount_sociallogin'] = github_login.serialize()
        session.save()
        request.session = session

        # Set up an matching Persona SocialLogin for request
        persona_account = SocialAccount.objects.create(
            user=github_account.user,
            provider='persona',
            uid=github_account.user.email)
        persona_login = SocialLogin(account=persona_account)

        # Verify the social_login receiver over-writes the provider
        # stored in the session
        self.adapter.pre_social_login(request, persona_login)
        session = request.session
        eq_(session['sociallogin_provider'], 'persona')
Exemple #16
0
    def test_pre_social_login_same_provider(self):
        """
        pre_social_login passes if existing provider is the same.

        I'm not sure what the real-world counterpart of this is. Logging
        in with a different GitHub account? Needed for branch coverage.
        """

        # Set up a GitHub SocialLogin in the session
        github_account = SocialAccount.objects.get(user__username='******')
        github_login = SocialLogin(account=github_account,
                                   user=github_account.user)

        request = self.rf.get('/')
        session = self.client.session
        session['sociallogin_provider'] = 'github'
        session['socialaccount_sociallogin'] = github_login.serialize()
        session.save()
        request.session = session

        # Set up an un-matching GitHub SocialLogin for request
        github2_account = SocialAccount(user=self.user_model(),
                                        provider='github',
                                        uid=github_account.uid + '2')
        github2_login = SocialLogin(account=github2_account)

        self.adapter.pre_social_login(request, github2_login)
        assert 'github' == request.session['sociallogin_provider']
Exemple #17
0
    def test_pre_social_login_error_for_unmatched_login(self):
        """
        When we suspect the signup form is used as a connection form, abort.

        https://bugzil.la/1063830
        """
        # Set up a GitHub SocialLogin in the session
        github_account = SocialAccount.objects.get(user__username='******')
        github_login = SocialLogin(account=github_account,
                                   user=github_account.user)

        request = self.rf.get('/')
        session = self.client.session
        session['socialaccount_sociallogin'] = github_login.serialize()
        session.save()
        request.session = session
        messages = self.get_messages(request)

        # Set up an un-matching alternate SocialLogin for request
        other_account = SocialAccount(user=self.user_model(),
                                      provider='other',
                                      uid='*****@*****.**')
        other_login = SocialLogin(account=other_account)

        self.assertRaises(ImmediateHttpResponse, self.adapter.pre_social_login,
                          request, other_login)
        queued_messages = list(messages)
        eq_(len(queued_messages), 1)
        eq_(django_messages.ERROR, queued_messages[0].level)
Exemple #18
0
    def save_user(self, request, sociallogin: SocialLogin, form=None):
        if not form:
            # A subscription form is enforced by settings.SOCIALACCOUNT_AUTO_SIGNUP
            # If subscription form is bypassed, the subscription can't proceed.
            raise DootixAdapterError("Subscription form is missing.")

        user = sociallogin.user
        user.set_unusable_password()
        user.first_name = form.cleaned_data.get("first_name")
        user.last_name = form.cleaned_data.get("last_name")
        user.username = form.cleaned_data.get("username")

        sociallogin.save(request)

        PermitAuthor.objects.create(
            user=user,
            address=form.cleaned_data["address"],
            zipcode=form.cleaned_data["zipcode"],
            city=form.cleaned_data["city"],
            phone_first=form.cleaned_data["phone_first"],
            phone_second=form.cleaned_data["phone_second"],
            company_name=form.cleaned_data["company_name"],
            vat_number=form.cleaned_data["vat_number"],
        )

        return user
Exemple #19
0
    def _create_request(self, provider, process, user, url, method, data=None):

        factory = RequestFactory()
        request = factory.get('/accounts/login/callback/')

        factory = RequestFactory()
        if method == 'GET':
            request = factory.get(url)
        else:
            request = factory.post(url, data)

        request.user = AnonymousUser()
        SessionMiddleware().process_request(request)
        MessageMiddleware().process_request(request)

        user = LocalUser(username='******', email='*****@*****.**')
        account = SocialAccount(user=user, provider=provider, uid='123')
        sociallogin = SocialLogin(user=user, account=account)

        if process is not None:
            sociallogin.state['process'] = process

        complete_social_login(request, sociallogin)

        return request
Exemple #20
0
    def test_pre_social_login_matched_login(self):
        """
        https://bugzil.la/1063830, happy path

        A user tries to sign in with GitHub, but their GitHub email matches
        an existing Persona-backed MDN account. They follow the prompt to login
        with Persona, and the accounts are connected.
        """

        # Set up a GitHub SocialLogin in the session
        github_account = SocialAccount.objects.get(user__username='******')
        github_login = SocialLogin(account=github_account,
                                   user=github_account.user)

        request = self.rf.get('/')
        session = self.client.session
        session['sociallogin_provider'] = 'github'
        session['socialaccount_sociallogin'] = github_login.serialize()
        session.save()
        request.session = session

        # Set up an matching Persona SocialLogin for request
        persona_account = SocialAccount.objects.create(
            user=github_account.user,
            provider='persona',
            uid=github_account.user.email)
        persona_login = SocialLogin(account=persona_account)

        # Verify the social_login receiver over-writes the provider
        # stored in the session
        self.adapter.pre_social_login(request, persona_login)
        session = request.session
        eq_(session['sociallogin_provider'], 'persona')
Exemple #21
0
    def test_pre_social_login_error_for_unmatched_login(self):
        """
        When we suspect the signup form is used as a connection form, abort.

        https://bugzil.la/1063830
        """
        # Set up a GitHub SocialLogin in the session
        github_account = SocialAccount.objects.get(user__username='******')
        github_login = SocialLogin(account=github_account,
                                   user=github_account.user)

        request = self.rf.get('/')
        session = self.client.session
        session['socialaccount_sociallogin'] = github_login.serialize()
        session.save()
        request.session = session
        messages = self.get_messages(request)

        # Set up an un-matching alternate SocialLogin for request
        other_account = SocialAccount(user=self.user_model(),
                                      provider='other',
                                      uid='*****@*****.**')
        other_login = SocialLogin(account=other_account)

        self.assertRaises(ImmediateHttpResponse,
                          self.adapter.pre_social_login, request, other_login)
        queued_messages = list(messages)
        assert len(queued_messages) == 1
        assert queued_messages[0].level == django_messages.ERROR
Exemple #22
0
    def test_pre_social_login_same_provider(self):
        """
        pre_social_login passes if existing provider is the same.

        I'm not sure what the real-world counterpart of this is. Logging
        in with a different GitHub account? Needed for branch coverage.
        """

        # Set up a GitHub SocialLogin in the session
        github_account = SocialAccount.objects.get(user__username='******')
        github_login = SocialLogin(account=github_account,
                                   user=github_account.user)

        request = self.rf.get('/')
        session = self.client.session
        session['sociallogin_provider'] = 'github'
        session['socialaccount_sociallogin'] = github_login.serialize()
        session.save()
        request.session = session

        # Set up an un-matching GitHub SocialLogin for request
        github2_account = SocialAccount(user=self.user_model(),
                                        provider='github',
                                        uid=github_account.uid + '2')
        github2_login = SocialLogin(account=github2_account)

        self.adapter.pre_social_login(request, github2_login)
        eq_(request.session['sociallogin_provider'], 'github')
Exemple #23
0
    def test_pre_social_login_matched_login(self):
        """
        When we detected a legacy Persona account, advise recovery of account.

        A user tries to sign in with GitHub, but their GitHub email matches
        an existing MDN account backed by Persona. They are prompted to
        recover the existing account.

        https://bugzil.la/1063830, happy path
        """
        # Set up a session-only GitHub SocialLogin
        # These are created at the start of the signup process, and saved on
        #  profile completion.
        github_account = SocialAccount.objects.get(user__username='******')
        github_login = SocialLogin(account=github_account,
                                   user=github_account.user)

        # Setup existing Persona SocialLogin for the same email
        SocialAccount.objects.create(
            user=github_account.user,
            provider='persona',
            uid=github_account.user.email)

        request = self.rf.get('/')
        session = self.client.session
        session['sociallogin_provider'] = 'github'
        session['socialaccount_sociallogin'] = github_login.serialize()
        session.save()
        request.session = session

        # Verify the social_login receiver over-writes the provider
        # stored in the session
        self.adapter.pre_social_login(request, github_login)
        session = request.session
        eq_(session['sociallogin_provider'], 'github')
Exemple #24
0
 def dispatch(self, request):
     callback_url = reverse(self.adapter.provider_id + "_callback")
     SocialLogin.stash_state(request)
     client = self._get_client(request, callback_url)
     try:
         return client.get_redirect()
     except OAuthError:
         return render_authentication_error(request)
Exemple #25
0
 def dispatch(self, request):
     callback_url = reverse(self.adapter.provider_id + "_callback")
     SocialLogin.stash_state(request)
     client = self._get_client(request, callback_url)
     try:
         return client.get_redirect()
     except OAuthError:
         return render_authentication_error(request)
Exemple #26
0
 def dispatch(self, request):
     """
     Redirects to the CAS server login page.
     """
     action = request.GET.get('action', AuthAction.AUTHENTICATE)
     SocialLogin.stash_state(request)
     client = self.get_client(request, action=action)
     return HttpResponseRedirect(client.get_login_url())
Exemple #27
0
def login(request):
    if 'openid' in request.GET or request.method == 'POST':
        form = LoginForm(
            dict(list(request.GET.items()) + list(request.POST.items()))
        )
        if form.is_valid():
            client = _openid_consumer(request)
            provider = OpenIDProvider(request)
            realm = provider.get_settings().get(
                'REALM',
                request.build_absolute_uri('/'))
            try:
                auth_request = client.begin(form.cleaned_data['openid'])
                if QUERY_EMAIL:
                    sreg = SRegRequest()
                    for name in SRegFields:
                        sreg.requestField(field_name=name,
                                          required=True)
                    auth_request.addExtension(sreg)
                    ax = FetchRequest()
                    for name in AXAttributes:
                        ax.add(AttrInfo(name,
                                        required=True))
                    provider = OpenIDProvider(request)
                    server_settings = \
                        provider.get_server_settings(request.GET.get('openid'))
                    extra_attributes = \
                        server_settings.get('extra_attributes', [])
                    for _, name, required in extra_attributes:
                        ax.add(AttrInfo(name,
                                        required=required))
                    auth_request.addExtension(ax)
                callback_url = reverse(callback)
                SocialLogin.stash_state(request)
                # Fix for issues 1523 and 2072 (github django-allauth)
                if 'next' in form.cleaned_data and form.cleaned_data['next']:
                    auth_request.return_to_args['next'] = \
                        form.cleaned_data['next']
                redirect_url = auth_request.redirectURL(
                    realm,
                    request.build_absolute_uri(callback_url))
                return HttpResponseRedirect(redirect_url)
            # UnicodeDecodeError:
            # see https://github.com/necaris/python3-openid/issues/1
            except (UnicodeDecodeError, DiscoveryFailure) as e:
                if request.method == 'POST':
                    form._errors["openid"] = form.error_class([e])
                else:
                    return render_authentication_error(
                        request,
                        OpenIDProvider.id,
                        exception=e)
    else:
        form = LoginForm(initial={'next': request.GET.get('next'),
                                  'process': request.GET.get('process')})
    d = dict(form=form)
    return render(request, "openid/login.html", d)
Exemple #28
0
def _get_sociallogin(user, provider):
    """
    Returns an ready sociallogin object for the given auth provider.
    """
    socialaccount = SocialAccount(user=user, uid='1234', provider=provider)
    socialaccount.extra_data = {'email': user.email}
    sociallogin = SocialLogin()
    sociallogin.account = socialaccount
    return sociallogin
def sociallogin(client, user_model):
    account = SocialAccount(provider="google")
    sociallogin = SocialLogin(
        account=account,
        user=user_model(),
    )
    session = client.session
    session["socialaccount_sociallogin"] = sociallogin.serialize()
    session.save()
    return sociallogin
Exemple #30
0
 def dispatch(self, request):
     callback_url = reverse(self.adapter.provider_id + "_callback")
     SocialLogin.stash_state(request)
     action = request.GET.get("action", AuthAction.AUTHENTICATE)
     provider = self.adapter.get_provider()
     auth_url = provider.get_auth_url(request, action) or self.adapter.authorize_url
     client = self._get_client(request, callback_url)
     try:
         return client.get_redirect(auth_url)
     except OAuthError as e:
         return render_authentication_error(request, self.adapter.provider_id, exception=e)
Exemple #31
0
 def dispatch(self, request):
     provider = self.provider
     callback_url = reverse(provider.slug + "_callback")
     SocialLogin.stash_state(request)
     action = request.GET.get('action', AuthAction.AUTHENTICATE)
     auth_url = provider.get_auth_url(request, action) or provider.get_authorize_url(request)
     auth_params = provider.get_auth_params(request, action)
     client = self._get_client(request, callback_url)
     try:
         return client.get_redirect(auth_url, auth_params)
     except OAuthError as e:
         return render_authentication_error(request, provider.slug, exception=e)
 def dispatch(self, request):
     callback_url = reverse(self.adapter.provider_id + "_callback")
     SocialLogin.stash_state(request)
     action = request.GET.get('action', AuthAction.AUTHENTICATE)
     provider = self.adapter.get_provider()
     auth_url = provider.get_auth_url(request, action) \
         or self.adapter.authorize_url
     client = self._get_client(request, callback_url)
     try:
         return client.get_redirect(auth_url)
     except OAuthError:
         return render_authentication_error(request)
Exemple #33
0
    def dispatch(self, request):
        if 'openid' in request.GET or request.method == 'POST':
            form = LoginForm(
                dict(list(request.GET.items()) + list(request.POST.items())))
            if form.is_valid():
                client = _openid_consumer(request)
                try:
                    auth_request = client.begin(form.cleaned_data['openid'])
                    provider = self.provider
                    app = provider.get_app(request)

                    if QUERY_EMAIL:
                        sreg = SRegRequest()
                        for name in SRegFields:
                            sreg.requestField(field_name=name, required=True)
                        auth_request.addExtension(sreg)
                        ax = FetchRequest()
                        for name in AXAttributes:
                            ax.add(AttrInfo(name, required=True))
                        server_settings = provider.get_server_settings(
                            request.GET.get('openid'))
                        extra_attributes = server_settings.get(
                            'extra_attributes', [])
                        for _, name, required in extra_attributes:
                            ax.add(AttrInfo(name, required=required))
                        auth_request.addExtension(ax)

                    callback_url = provider.get_callback_url(request, app)
                    SocialLogin.stash_state(request)
                    # https://github.com/pennersr/django-allauth/issues/1523
                    auth_request.return_to_args['next'] = \
                        form.cleaned_data.get('next', '/')
                    redirect_url = auth_request.redirectURL(
                        request.build_absolute_uri('/'),
                        request.build_absolute_uri(callback_url))
                    return HttpResponseRedirect(redirect_url)
                # UnicodeDecodeError:
                # see https://github.com/necaris/python3-openid/issues/1
                except (UnicodeDecodeError, DiscoveryFailure) as e:
                    if request.method == 'POST':
                        form._errors["openid"] = form.error_class([e])
                    else:
                        return render_authentication_error(request,
                                                           self.provider.id,
                                                           exception=e)
        else:
            form = LoginForm(
                initial={
                    'next': request.GET.get('next'),
                    'process': request.GET.get('process')
                })
        d = dict(form=form)
        return render(request, "openid/login.html", d)
    def validate_state(self, value):
        """Validate the state is equal to the one stored in the session."""
        try:
            SocialLogin.verify_and_unstash_state(
                self.context['request'],
                value,
            )
        # Allauth raises PermissionDenied if the validation fails
        except PermissionDenied:
            raise ValidationError(_('State did not match.'))

        return value
Exemple #35
0
def _get_sociallogin(user, provider):
    """
    Returns an ready sociallogin object for the given auth provider.
    """
    socialaccount = SocialAccount(
        user=user,
        uid='1234',
        provider=provider,
    )
    socialaccount.extra_data = {'email': user.email}
    sociallogin = SocialLogin()
    sociallogin.account = socialaccount
    return sociallogin
Exemple #36
0
def login(request):
    app = providers.registry.by_id(
        DraugiemProvider.id, request).get_app(request)
    redirect_url = request.build_absolute_uri(reverse(callback))
    redirect_url_hash = md5((
        app.secret + redirect_url).encode('utf-8')).hexdigest()
    params = {
        'app': app.client_id,
        'hash': redirect_url_hash,
        'redirect': redirect_url,
    }
    SocialLogin.stash_state(request)
    return HttpResponseRedirect('%s?%s' % (AUTHORIZE_URL, urlencode(params)))
Exemple #37
0
 def dispatch(self, request):
     callback_url = reverse(self.adapter.provider_id + "_callback")
     SocialLogin.stash_state(request)
     action = request.GET.get('action', AuthAction.AUTHENTICATE)
     provider = self.adapter.get_provider()
     auth_url = provider.get_auth_url(request, action) or self.adapter.authorize_url
     client = self._get_client(request, callback_url)
     try:
         return client.get_redirect(auth_url)
     except OAuthError as e:
         return render_authentication_error(request, {'error': e.message})
     except Exception as ex:
         send_social_connection_error_email(request, {'error': ex.message})
Exemple #38
0
def login(request):
    app = providers.registry.by_id(DraugiemProvider.id,
                                   request).get_app(request)
    redirect_url = request.build_absolute_uri(reverse(callback))
    redirect_url_hash = md5(
        (app.secret + redirect_url).encode("utf-8")).hexdigest()
    params = {
        "app": app.client_id,
        "hash": redirect_url_hash,
        "redirect": redirect_url,
    }
    SocialLogin.stash_state(request)
    return HttpResponseRedirect("%s?%s" % (AUTHORIZE_URL, urlencode(params)))
Exemple #39
0
def callback(request):
    client = _openid_consumer(request)
    response = client.complete(dict(request.REQUEST.items()), request.build_absolute_uri(request.path))
    if response.status == consumer.SUCCESS:
        account = SocialAccount(uid=response.identity_url, provider=OpenIDProvider.id, extra_data={})
        account.user = get_adapter().populate_new_user(request, account, email=_get_email_from_response(response))
        login = SocialLogin(account)
        login.state = SocialLogin.unstash_state(request)
        ret = complete_social_login(request, login)
    elif response.status == consumer.CANCEL:
        ret = HttpResponseRedirect(reverse("socialaccount_login_cancelled"))
    else:
        ret = render_authentication_error(request)
    return ret
Exemple #40
0
 def login(self, request, *args, **kwargs):
     callback_url = reverse(self.adapter.provider_id + "_callback")
     SocialLogin.stash_state(request)
     action = request.GET.get("action", AuthAction.AUTHENTICATE)
     provider = self.adapter.get_provider()
     auth_url = provider.get_auth_url(request, action) or self.adapter.authorize_url
     auth_params = provider.get_auth_params(request, action)
     client = self._get_client(request, callback_url)
     try:
         return client.get_redirect(auth_url, auth_params)
     except OAuthError as e:
         return render_authentication_error(
             request, self.adapter.provider_id, exception=e
         )
Exemple #41
0
 def dispatch(self, request):
     app = self.provider.get_app(request)
     redirect_url = request.build_absolute_uri(
         reverse(self.provider.callback_view))
     redirect_url_hash = md5(
         (app.secret + redirect_url).encode('utf-8')).hexdigest()
     params = {
         'app': app.client_id,
         'hash': redirect_url_hash,
         'redirect': redirect_url,
     }
     SocialLogin.stash_state(request)
     return HttpResponseRedirect('%s?%s' %
                                 (AUTHORIZE_URL, urlencode(params)))
Exemple #42
0
 def get(self, *args, **kwargs):
     user = BadgeUser.objects.get(pk=kwargs['id'])
     social_account = user.get_social_account()
     get_adapter(self.request).logout(self.request)
     sociallogin = SocialLogin(account=social_account, email_addresses=[email for email in user.email_items])
     sociallogin.user = user
     badgr_app = BadgrApp.objects.filter(pk=user.badgrapp_id).first()
     if not badgr_app:
         badgr_app = BadgrApp.objects.all().first()
     set_session_badgr_app(self.request, badgr_app)
     ret = perform_login(self.request, sociallogin.user,
                   email_verification=app_settings.EMAIL_VERIFICATION,
                   redirect_url=sociallogin.get_redirect_url(self.request),
                   signal_kwargs={"sociallogin": sociallogin})
     return ret
Exemple #43
0
def login(request):
    app = providers.registry.by_id(DraugiemProvider.id).get_app(request)
    request_scheme = request.META['wsgi.url_scheme']
    request_host = request.META['HTTP_HOST']
    request_path = reverse(callback)
    redirect_url = '%s://%s%s' % (request_scheme, request_host, request_path)
    redirect_url_hash = md5((
        app.secret + redirect_url).encode('utf-8')).hexdigest()
    params = {
        'app': app.client_id,
        'hash': redirect_url_hash,
        'redirect': redirect_url,
    }
    SocialLogin.stash_state(request)
    return HttpResponseRedirect('%s?%s' % (AUTHORIZE_URL, urlencode(params)))
    def dispatch(self, request, *args, **kwargs):
        auth_error = get_request_param(request, "error")
        code = get_request_param(request, "code")
        if auth_error or not code:
            # Distinguish cancel from error
            if auth_error == self.adapter.login_cancelled_error:
                error = AuthError.CANCELLED
            else:
                error = AuthError.UNKNOWN
            return render_authentication_error(request,
                                               self.adapter.provider_id,
                                               error=error)

        app = self.adapter.get_provider().get_app(self.request)
        client = self.get_client(self.request, app)

        try:
            token_data = self.adapter.get_access_token_data(self.request,
                                                            app=app,
                                                            client=client)
            token = self.adapter.parse_token(data=token_data)
            token.app = app

            login = self.adapter.complete_login(request,
                                                app,
                                                token,
                                                response=token_data)
            login.token = token

            state = get_request_param(request, "state")

            if self.adapter.supports_state:
                login.state = SocialLogin.verify_and_unstash_state(
                    request, state)
            else:
                login.state = SocialLogin.unstash_state(request)

            return complete_social_login(request, login)

        except (
                PermissionDenied,
                OAuth2Error,
                RequestException,
                ProviderException,
        ) as e:
            return render_authentication_error(request,
                                               self.adapter.provider_id,
                                               exception=e)
Exemple #45
0
def login_by_token(request):
    ret = None
    if request.method == 'POST':
        form = FacebookConnectForm(request.POST)
        if form.is_valid():
            try:
                provider = providers.registry.by_id(FacebookProvider.id)
                app = providers.registry.by_id(FacebookProvider.id) \
                    .get_app(request)
                access_token = form.cleaned_data['access_token']
                info = requests.get(
                    'https://graph.facebook.com/oauth/access_token_info',
                    params={
                        'client_id': app.client_id,
                        'access_token': access_token
                    })
                nonce = provider.get_nonce(request, pop=True)
                if nonce and nonce == info.json().get('auth_nonce'):
                    token = SocialToken(app=app, token=access_token)
                    login = fb_complete_login(request, app, token)
                    login.token = token
                    login.state = SocialLogin.state_from_request(request)
                    ret = complete_social_login(request, login)
            except requests.RequestException:
                logger.exception('Error accessing FB user profile')
    if not ret:
        ret = render_authentication_error(request)
    return ret
Exemple #46
0
        def post(self, request, provider=None, params=None, **kwargs):
            from requests import RequestException
            from allauth.socialaccount import providers
            from allauth.socialaccount.helpers import complete_social_login
            from allauth.socialaccount.models import SocialLogin, SocialToken
            from allauth.socialaccount.providers.facebook.provider import FacebookProvider

            if provider == 'facebook':
                try:
                    app = providers.registry.by_id(FacebookProvider.id).get_app(request)
                    token = SocialToken(app=app, token=params.access_token)
                    login = fb_complete_login(request, app, token)
                    login.token = token
                    login.state = SocialLogin.state_from_request(request)
                    ret = complete_social_login(request, login)
                except RequestException:
                    return http.HttpBadRequest('Error accessing FB user profile')
                else:
                    # If user does not exist
                    if login.account.user.id is None:
                        return http.HttpBadRequest('Not registered')

                    return self._construct_login_response(login.account.user)

            return http.HttpBadRequest('Invalid provider')
Exemple #47
0
def login_by_token(request):
    log.debug("login_by_token")
    ret = None
    if request.method == 'POST':
        form = FacebookConnectForm(request.POST)
        if form.is_valid():
            log.debug("Form is valid")
            try:
                app = providers.registry.by_id(FacebookProvider.id) \
                    .get_app(request)
                log.debug("App exists")
                access_token = form.cleaned_data['access_token']
                log.debug("access token exists")
                token = SocialToken(app=app,
                                    token=access_token)
                log.debug("social token created")
                login = fb_complete_login(app, token)
                log.debug("fb login complete")
                login.token = token
                login.state = SocialLogin.state_from_request(request)
                ret = complete_social_login(request, login)
            except:
                # FIXME: Catch only what is needed
                pass
    if not ret:
        log.debug("authentication error")
        ret = render_authentication_error(request)
    return ret
Exemple #48
0
def login(request):
    if 'openid' in request.GET or request.method == 'POST':
        form = LoginForm(request.REQUEST)
        if form.is_valid():
            client = _openid_consumer(request)
            try:
                auth_request = client.begin(form.cleaned_data['openid'])
                if QUERY_EMAIL:
                    sreg = SRegRequest()
                    sreg.requestField(field_name=SRegField.EMAIL, required=True)
                    auth_request.addExtension(sreg)
                    ax = FetchRequest()
                    ax.add(AttrInfo(AXAttribute.CONTACT_EMAIL,
                                    required=True))
                    auth_request.addExtension(ax)
                callback_url = reverse(callback)
                state = SocialLogin.marshall_state(request)
                callback_url = callback_url + '?' + urlencode(dict(state=state))
                redirect_url = auth_request.redirectURL(
                    request.build_absolute_uri('/'),
                    request.build_absolute_uri(callback_url))
                return HttpResponseRedirect(redirect_url)
            except DiscoveryFailure, e:
                if request.method == 'POST':
                    form._errors["openid"] = form.error_class([e])
                else:
                    return render_authentication_error(request)
    def post(self, request):
        data = JSONParser().parse(request)
        access_token = data.get('access_token', '')

        try:
            app = SocialApp.objects.get(provider="facebook")
            token = SocialToken(app=app, token=access_token)

            # check token against facebook
            login = fb_complete_login(app, token)
            login.token = token
            login.state = SocialLogin.state_from_request(request)

            # add or update the user into users table
            ret = complete_social_login(request, login)

            # if we get here we've succeeded
            return Response(status=200, data={
                'success': True,
                'username': request.user.username,
                'user_id': request.user.pk,
            })

        except:

            return Response(status=401 ,data={
                'success': False,
                'reason': "Bad Access Token",
            })
Exemple #50
0
    def post(self, Request):
        serializer = UserLoginSerializer(data=Request.data)
        if serializer.is_valid():
            request_data = serializer.data
            userId = request_data.get('fbuserId','')
            access_token = Request.data.get('access_token','')
            try:
                app = SocialApp.objects.get(provider="facebook")
                token = SocialToken(app=app,token=access_token)
                login = fb_complete_login(Request, app, token)
                login.token = token
                login.state = SocialLogin.state_from_request(Request)
                user = UserLogin.objects.all().filter(fbuserId = userId)
                # ret = complete_social_login(Request, login)

                if len(user) == 0:
                    serializer.save()
                    return Response(status=200 ,data={
                         'success': True,
                         'reason': "User created",
                         'data':user.values()

                    })
                else:
                    return Response(status=200 ,data={
                         'success': False,
                         'reason': "User already exist",
                         'data':user.values()
                     })
            except Exception,e:
                  return Response(status=400 ,data={
                         'success': False,
                         'reason':e,
                     })
Exemple #51
0
def persona_login(request):
    assertion = request.POST.get('assertion', '')
    settings = app_settings.PROVIDERS.get(PersonaProvider.id, {})
    audience = settings.get('AUDIENCE', None)
    if audience is None:
        raise ImproperlyConfigured("No Persona audience configured. Please "
                                   "add an AUDIENCE item to the "
                                   "SOCIALACCOUNT_PROVIDERS['persona'] setting.")

    resp = requests.post('https://verifier.login.persona.org/verify',
                         {'assertion': assertion,
                          'audience': audience})
    try:
        resp.raise_for_status()
        extra_data = resp.json()
        if extra_data['status'] != 'okay':
            return render_authentication_error(
                request,
                provider_id=PersonaProvider.id,
                extra_context={'response': extra_data})
    except (ValueError, requests.RequestException) as e:
        return render_authentication_error(
            request,
            provider_id=PersonaProvider.id,
            exception=e)
    login = providers.registry \
        .by_id(PersonaProvider.id) \
        .sociallogin_from_response(request, extra_data)
    login.state = SocialLogin.state_from_request(request)
    return complete_social_login(request, login)
Exemple #52
0
def callback(request):
    if 'dr_auth_status' not in request.GET:
        return render_authentication_error(
            request, DraugiemProvider.id, error=AuthError.UNKNOWN)

    if request.GET['dr_auth_status'] != 'ok':
        return render_authentication_error(
            request, DraugiemProvider.id, error=AuthError.DENIED)

    if 'dr_auth_code' not in request.GET:
        return render_authentication_error(
            request, DraugiemProvider.id, error=AuthError.UNKNOWN)

    ret = None
    auth_exception = None
    try:
        app = providers.registry.by_id(
            DraugiemProvider.id, request).get_app(request)
        login = draugiem_complete_login(
            request, app, request.GET['dr_auth_code'])
        login.state = SocialLogin.unstash_state(request)

        ret = complete_social_login(request, login)
    except (requests.RequestException, DraugiemApiError) as e:
        auth_exception = e

    if not ret:
        ret = render_authentication_error(
            request, DraugiemProvider.id, exception=auth_exception)

    return ret
Exemple #53
0
    def pre_social_login(self, request, sociallogin):
        """
        Invoked just after a user successfully authenticates via a
        social provider, but before the login is actually processed.

        We use it to:
            1. Check if the user is connecting accounts via signup page
            2. store the name of the socialaccount provider in the user's session.
        """
        session_login_data = request.session.get('socialaccount_sociallogin', None)
        request_login = sociallogin

        # Is there already a sociallogin_provider in the session?
        if session_login_data:
            session_login = SocialLogin.deserialize(session_login_data)
            # If the provider in the session is different from the provider in the
            # request, the user is connecting a new provider to an existing account
            if session_login.account.provider != request_login.account.provider:
                # Does the request sociallogin match an existing user?
                if not request_login.is_existing:
                    # go straight back to signup page with an error message
                    # BEFORE allauth over-writes the session sociallogin
                    level = messages.ERROR
                    message = "socialaccount/messages/account_not_found.txt"
                    get_adapter().add_message(request, level, message)
                    raise ImmediateHttpResponse(
                        redirect('socialaccount_signup')
                    )
        # TODO: Can the code that uses this just use request.session['socialaccount_sociallogin'].account.provider instead?
        request.session['sociallogin_provider'] = (sociallogin
                                                   .account.provider)
        request.session.modified = True
Exemple #54
0
    def sociallogin_from_response(self, request, response):
        """
        Instantiates and populates a `SocialLogin` model based on the data
        retrieved in `response`. The method does NOT save the model to the
        DB.

        Data for `SocialLogin` will be extracted from `response` with the
        help of the `.extract_uid()`, `.extract_extra_data()`,
        `.extract_common_fields()`, and `.extract_email_addresses()`
        methods.

        :param request: a Django `HttpRequest` object.
        :param response: object retrieved via the callback response of the
            social auth provider.
        :return: A populated instance of the `SocialLogin` model (unsaved).
        """
        # NOTE: Avoid loading models at top due to registry boot...
        from allauth.socialaccount.models import SocialLogin, SocialAccount

        adapter = get_adapter(request)
        uid = self.extract_uid(response)
        extra_data = self.extract_extra_data(response)
        common_fields = self.extract_common_fields(response)
        socialaccount = SocialAccount(extra_data=extra_data,
                                      uid=uid,
                                      provider=self.id)
        email_addresses = self.extract_email_addresses(response)
        self.cleanup_email_addresses(common_fields.get('email'),
                                     email_addresses)
        sociallogin = SocialLogin(account=socialaccount,
                                  email_addresses=email_addresses)
        user = sociallogin.user = adapter.new_user(request, sociallogin)
        user.set_unusable_password()
        adapter.populate_user(request, sociallogin, common_fields)
        return sociallogin
Exemple #55
0
def api_twitter_connect_by_token(request):
    ret = None
    if request.method == 'POST':
        try:
            adapter = TwitterOAuthAdapter()
            app = adapter.get_provider().get_app(request)
            access_token = request.POST.get('access_token')
            access_token_secret = request.POST.get('access_token_secret')
            token = SocialToken(app=app, token=access_token)
            login = twitter_complete_login(request, app, access_token, access_token_secret)

            login.token = token
            login.state = SocialLogin.state_from_request(request)
            ret = complete_social_login(request, login)
        except Exception as e:
            # FIXME: Catch only what is needed
            pass

    if not ret:
        raise Http404

    profile = Profile.objects.get_or_create(user=request.user)[0]
    profile.avatar_url = login.account.get_avatar_url()
    profile.save()
    user_source = UserResource()
    bundle = user_source.build_bundle(obj=request.user, request=request)
    bundle = user_source.full_dehydrate(bundle)
    bundle = user_source.alter_detail_data_to_serialize(request, bundle)
    return user_source.create_response(request, bundle)
Exemple #56
0
    def post(self, request):
        if 'dr_auth_status' not in request.GET:
            return render_authentication_error(request,
                                               self.provider.id,
                                               error=AuthError.UNKNOWN)

        if request.GET['dr_auth_status'] != 'ok':
            return render_authentication_error(request,
                                               self.provider.id,
                                               error=AuthError.DENIED)

        if 'dr_auth_code' not in request.GET:
            return render_authentication_error(request,
                                               self.provider.id,
                                               error=AuthError.UNKNOWN)

        ret = None
        auth_exception = None
        try:
            app = self.provider.get_app(request)
            login = draugiem_complete_login(request, app,
                                            request.GET['dr_auth_code'])
            login.state = SocialLogin.unstash_state(request)

            ret = complete_social_login(request, login)
        except (requests.RequestException, DraugiemApiError) as e:
            auth_exception = e

        if not ret:
            ret = render_authentication_error(request,
                                              self.provider.id,
                                              exception=auth_exception)

        return ret
Exemple #57
0
 def dispatch(self, request):
     """
     View to handle final steps of OAuth based authentication where the user
     gets redirected back to from the service provider
     """
     login_done_url = reverse(self.adapter.provider_id + "_callback")
     client = self._get_client(request, login_done_url)
     if not client.is_valid():
         if 'denied' in request.GET:
             return HttpResponseRedirect(reverse('socialaccount_login_cancelled'))
         extra_context = dict(oauth_client=client)
         return render_authentication_error(request, extra_context)
     app = self.adapter.get_provider().get_app(request)
     try:
         access_token = client.get_access_token()
         token = SocialToken(app=app,
                             token=access_token['oauth_token'],
                             token_secret=access_token['oauth_token_secret'])
         login = self.adapter.complete_login(request, app, token)
         token.account = login.account
         login.token = token
         login.state = SocialLogin.unstash_state(request)
         return complete_social_login(request, login)
     except OAuthError:
         return render_authentication_error(request)
Exemple #58
0
    def pre_social_login(self, request, sociallogin):
        """
        Invoked just after a user successfully authenticates via a
        social provider, but before the login is actually processed.

        We use it to:
            1. Check if the user is connecting accounts via signup page
            2. store the name of the socialaccount provider in the user's session.
        """
        session_login_data = request.session.get('socialaccount_sociallogin',
                                                 None)
        request_login = sociallogin

        # Is there already a sociallogin_provider in the session?
        if session_login_data:
            session_login = SocialLogin.deserialize(session_login_data)
            # If the provider in the session is different from the provider in the
            # request, the user is connecting a new provider to an existing account
            if session_login.account.provider != request_login.account.provider:
                # Does the request sociallogin match an existing user?
                if not request_login.is_existing:
                    # go straight back to signup page with an error message
                    # BEFORE allauth over-writes the session sociallogin
                    level = messages.ERROR
                    message = "socialaccount/messages/account_not_found.txt"
                    get_adapter().add_message(request, level, message)
                    raise ImmediateHttpResponse(
                        redirect('socialaccount_signup'))
        # TODO: Can the code that uses this just use request.session['socialaccount_sociallogin'].account.provider instead?
        request.session['sociallogin_provider'] = (
            sociallogin.account.provider)
        request.session.modified = True
Exemple #59
0
def login_by_token(request):
    ret = None
    auth_exception = None

    if request.method == 'POST':
        form = KakaoConnectForm(request.POST)
        if form.is_valid():
            try:
                provider = providers.registry.by_id(KakaoProvider.id)
                app = providers.registry.by_id(KakaoProvider.id).get_app(request)
                access_token = form.cleaned_data['access_token']

                token = SocialToken(app=app, token=access_token)
                login = kakao_complete_login(request, app, token)
                login.token = token
                login.state = SocialLogin.state_from_request(request)
                ret = complete_social_login(request, login)
            except requests.RequestException as e:
                logger.exception('Error accessing KAKAO user profile')
                auth_exception = e

    if not ret:
        ret = render_authentication_error(request, KakaoProvider.id, exception+auth_exception)

    return ret