Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / target / twitter.py @ 0e79735c

History | View | Annotate | Download (6 kB)

1
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

    
34
import json
35
import logging
36

    
37
from django.http import HttpResponseBadRequest
38
from django.utils.translation import ugettext as _
39
from django.contrib import messages
40
from django.template import RequestContext
41
from django.views.decorators.http import require_http_methods
42
from django.http import HttpResponseRedirect
43
from django.core.urlresolvers import reverse
44
from django.core.exceptions import ImproperlyConfigured
45
from django.shortcuts import get_object_or_404
46

    
47
from urlparse import urlunsplit, urlsplit
48

    
49
from astakos.im.util import prepare_response, get_context, login_url
50
from astakos.im.views import requires_anonymous, render_response, \
51
        requires_auth_provider, required_auth_methods_assigned
52
from astakos.im.settings import ENABLE_LOCAL_ACCOUNT_MIGRATION, BASEURL
53
from astakos.im.models import AstakosUser, PendingThirdPartyUser
54
from astakos.im.forms import LoginForm
55
from astakos.im.activation_backends import get_backend, SimpleBackend
56
from astakos.im import settings
57
from astakos.im import auth_providers
58
from astakos.im.target import add_pending_auth_provider, get_pending_key, \
59
    handle_third_party_signup, handle_third_party_login, init_third_party_session
60

    
61
import astakos.im.messages as astakos_messages
62

    
63

    
64
logger = logging.getLogger(__name__)
65

    
66
import oauth2 as oauth
67
import cgi
68
import urllib
69

    
70
consumer = oauth.Consumer(settings.TWITTER_TOKEN, settings.TWITTER_SECRET)
71
client = oauth.Client(consumer)
72

    
73
request_token_url = 'http://twitter.com/oauth/request_token'
74
access_token_url = 'http://twitter.com/oauth/access_token'
75
authenticate_url = 'http://twitter.com/oauth/authenticate'
76

    
77
@requires_auth_provider('twitter', login=True)
78
@require_http_methods(["GET", "POST"])
79
def login(request):
80
    init_third_party_session(request)
81
    force_login = request.GET.get('force_login',
82
                                  settings.TWITTER_AUTH_FORCE_LOGIN)
83
    resp, content = client.request(request_token_url, "GET")
84
    if resp['status'] != '200':
85
        messages.error(request, 'Invalid Twitter response')
86
        return HttpResponseRedirect(reverse('edit_profile'))
87

    
88
    request.session['request_token'] = dict(cgi.parse_qsl(content))
89
    params = {
90
        'oauth_token': request.session['request_token']['oauth_token'],
91
    }
92
    if force_login:
93
        params['force_login'] = 1
94

    
95
    if request.GET.get('key', None):
96
        request.session['pending_key'] = request.GET.get('key')
97

    
98
    if request.GET.get('next', None):
99
        request.session['next_url'] = request.GET.get('next')
100

    
101
    url = "%s?%s" % (authenticate_url, urllib.urlencode(params))
102
    return HttpResponseRedirect(url)
103

    
104

    
105
@requires_auth_provider('twitter', login=True)
106
@require_http_methods(["GET", "POST"])
107
def authenticated(
108
    request,
109
    template='im/third_party_check_local.html',
110
    extra_context={}):
111

    
112
    next_url = None
113
    if 'next_url' in request.session:
114
        next_url = request.session['next_url']
115
        del request.session['next_url']
116

    
117
    if request.GET.get('denied'):
118
        return HttpResponseRedirect(reverse('edit_profile'))
119

    
120
    if not 'request_token' in request.session:
121
        messages.error(request, 'Twitter handshake failed')
122
        return HttpResponseRedirect(reverse('edit_profile'))
123

    
124
    token = oauth.Token(request.session['request_token']['oauth_token'],
125
        request.session['request_token']['oauth_token_secret'])
126
    client = oauth.Client(consumer, token)
127

    
128
    # Step 2. Request the authorized access token from Twitter.
129
    resp, content = client.request(access_token_url, "GET")
130
    if resp['status'] != '200':
131
        try:
132
            del request.session['request_token']
133
        except:
134
            pass
135
        messages.error(request, 'Invalid Twitter response')
136
        return HttpResponseRedirect(reverse('edit_profile'))
137

    
138
    access_token = dict(cgi.parse_qsl(content))
139
    userid = access_token['user_id']
140
    username = access_token.get('screen_name', userid)
141
    provider_info = {'screen_name': username}
142
    affiliation = 'Twitter.com'
143

    
144

    
145
    try:
146
        return handle_third_party_login(request, 'twitter', userid,
147
                                        provider_info, affiliation)
148
    except AstakosUser.DoesNotExist, e:
149
        third_party_key = get_pending_key(request)
150
        user_info = {'affiliation': affiliation}
151
        return handle_third_party_signup(request, userid, 'twitter',
152
                                         third_party_key,
153
                                         provider_info,
154
                                         user_info,
155
                                         template,
156
                                         extra_context)
157