Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / views / target / twitter.py @ a3e3917f

History | View | Annotate | Download (6.5 kB)

1 c101b32b Kostas Papadimitriou
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2 c101b32b Kostas Papadimitriou
#
3 c101b32b Kostas Papadimitriou
# Redistribution and use in source and binary forms, with or
4 c101b32b Kostas Papadimitriou
# without modification, are permitted provided that the following
5 c101b32b Kostas Papadimitriou
# conditions are met:
6 c101b32b Kostas Papadimitriou
#
7 c101b32b Kostas Papadimitriou
#   1. Redistributions of source code must retain the above
8 c101b32b Kostas Papadimitriou
#      copyright notice, this list of conditions and the following
9 c101b32b Kostas Papadimitriou
#      disclaimer.
10 c101b32b Kostas Papadimitriou
#
11 c101b32b Kostas Papadimitriou
#   2. Redistributions in binary form must reproduce the above
12 c101b32b Kostas Papadimitriou
#      copyright notice, this list of conditions and the following
13 c101b32b Kostas Papadimitriou
#      disclaimer in the documentation and/or other materials
14 c101b32b Kostas Papadimitriou
#      provided with the distribution.
15 c101b32b Kostas Papadimitriou
#
16 c101b32b Kostas Papadimitriou
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 c101b32b Kostas Papadimitriou
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 c101b32b Kostas Papadimitriou
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 c101b32b Kostas Papadimitriou
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 c101b32b Kostas Papadimitriou
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 c101b32b Kostas Papadimitriou
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 c101b32b Kostas Papadimitriou
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 c101b32b Kostas Papadimitriou
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 c101b32b Kostas Papadimitriou
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 c101b32b Kostas Papadimitriou
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 c101b32b Kostas Papadimitriou
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 c101b32b Kostas Papadimitriou
# POSSIBILITY OF SUCH DAMAGE.
28 c101b32b Kostas Papadimitriou
#
29 c101b32b Kostas Papadimitriou
# The views and conclusions contained in the software and
30 c101b32b Kostas Papadimitriou
# documentation are those of the authors and should not be
31 c101b32b Kostas Papadimitriou
# interpreted as representing official policies, either expressed
32 c101b32b Kostas Papadimitriou
# or implied, of GRNET S.A.
33 c101b32b Kostas Papadimitriou
34 c8d89a3c Kostas Papadimitriou
import logging
35 3c5a2b21 Kostas Papadimitriou
import oauth2 as oauth
36 3c5a2b21 Kostas Papadimitriou
import cgi
37 3c5a2b21 Kostas Papadimitriou
import urllib
38 c630fee6 Kostas Papadimitriou
39 c101b32b Kostas Papadimitriou
from django.contrib import messages
40 c101b32b Kostas Papadimitriou
from django.views.decorators.http import require_http_methods
41 29576723 Sofia Papagiannaki
from django.http import HttpResponseRedirect, urlencode
42 c101b32b Kostas Papadimitriou
from django.core.urlresolvers import reverse
43 3c5a2b21 Kostas Papadimitriou
from django.conf import settings as django_settings
44 c101b32b Kostas Papadimitriou
45 29576723 Sofia Papagiannaki
from urlparse import urlunsplit, urlsplit, parse_qsl
46 c101b32b Kostas Papadimitriou
47 3e0a032d Sofia Papagiannaki
from astakos.im.models import AstakosUser
48 c101b32b Kostas Papadimitriou
from astakos.im import settings
49 3e0a032d Sofia Papagiannaki
from astakos.im.views.target import get_pending_key, \
50 3e0a032d Sofia Papagiannaki
    handle_third_party_signup, handle_third_party_login, \
51 3e0a032d Sofia Papagiannaki
    init_third_party_session
52 3e0a032d Sofia Papagiannaki
from astakos.im.views.decorators import cookie_fix, requires_auth_provider
53 c101b32b Kostas Papadimitriou
54 c101b32b Kostas Papadimitriou
logger = logging.getLogger(__name__)
55 c101b32b Kostas Papadimitriou
56 c101b32b Kostas Papadimitriou
57 3c5a2b21 Kostas Papadimitriou
def django_setting(key, default):
58 3c5a2b21 Kostas Papadimitriou
    return getattr(django_settings, 'TWITTER_%s' % key.upper, default)
59 3c5a2b21 Kostas Papadimitriou
60 3c5a2b21 Kostas Papadimitriou
request_token_url = django_setting(
61 3c5a2b21 Kostas Papadimitriou
    'request_token_url',
62 3c5a2b21 Kostas Papadimitriou
    'https://api.twitter.com/oauth/request_token')
63 3c5a2b21 Kostas Papadimitriou
access_token_url = django_setting(
64 3c5a2b21 Kostas Papadimitriou
    'access_token_url',
65 3c5a2b21 Kostas Papadimitriou
    'https://api.twitter.com/oauth/access_token')
66 3c5a2b21 Kostas Papadimitriou
authenticate_url = django_setting(
67 3c5a2b21 Kostas Papadimitriou
    'authenticate_url',
68 3c5a2b21 Kostas Papadimitriou
    'https://api.twitter.com/oauth/authenticate')
69 3c5a2b21 Kostas Papadimitriou
70 c101b32b Kostas Papadimitriou
71 9d20fe23 Kostas Papadimitriou
@requires_auth_provider('twitter')
72 c101b32b Kostas Papadimitriou
@require_http_methods(["GET", "POST"])
73 222305b7 Sofia Papagiannaki
@cookie_fix
74 c101b32b Kostas Papadimitriou
def login(request):
75 0e79735c Kostas Papadimitriou
    init_third_party_session(request)
76 1c4e8364 Kostas Papadimitriou
    force_login = request.GET.get('force_login',
77 1c4e8364 Kostas Papadimitriou
                                  settings.TWITTER_AUTH_FORCE_LOGIN)
78 9d20fe23 Kostas Papadimitriou
    consumer = oauth.Consumer(settings.TWITTER_TOKEN,
79 9d20fe23 Kostas Papadimitriou
                              settings.TWITTER_SECRET)
80 9d20fe23 Kostas Papadimitriou
    client = oauth.Client(consumer)
81 c101b32b Kostas Papadimitriou
    resp, content = client.request(request_token_url, "GET")
82 c101b32b Kostas Papadimitriou
    if resp['status'] != '200':
83 c101b32b Kostas Papadimitriou
        messages.error(request, 'Invalid Twitter response')
84 e6d8c1c0 Kostas Papadimitriou
        logger.error("Invalid twitter response %s", resp)
85 e6d8c1c0 Kostas Papadimitriou
        return HttpResponseRedirect(reverse('edit_profile'))
86 e6d8c1c0 Kostas Papadimitriou
87 e6d8c1c0 Kostas Papadimitriou
    oa_resp = dict(cgi.parse_qsl(content))
88 e6d8c1c0 Kostas Papadimitriou
    if 'status' in oa_resp and oa_resp['status'] != '200':
89 e6d8c1c0 Kostas Papadimitriou
        messages.error(request, 'Invalid Twitter response')
90 e6d8c1c0 Kostas Papadimitriou
        logger.error("Invalid twitter response %s", resp)
91 c101b32b Kostas Papadimitriou
        return HttpResponseRedirect(reverse('edit_profile'))
92 c101b32b Kostas Papadimitriou
93 c101b32b Kostas Papadimitriou
    request.session['request_token'] = dict(cgi.parse_qsl(content))
94 1c4e8364 Kostas Papadimitriou
    params = {
95 1c4e8364 Kostas Papadimitriou
        'oauth_token': request.session['request_token']['oauth_token'],
96 1c4e8364 Kostas Papadimitriou
    }
97 1c4e8364 Kostas Papadimitriou
    if force_login:
98 1c4e8364 Kostas Papadimitriou
        params['force_login'] = 1
99 1c4e8364 Kostas Papadimitriou
100 dd5f8f4d Kostas Papadimitriou
    if request.GET.get('key', None):
101 dd5f8f4d Kostas Papadimitriou
        request.session['pending_key'] = request.GET.get('key')
102 dd5f8f4d Kostas Papadimitriou
103 64492c49 Kostas Papadimitriou
    if request.GET.get('next', None):
104 64492c49 Kostas Papadimitriou
        request.session['next_url'] = request.GET.get('next')
105 dd5f8f4d Kostas Papadimitriou
106 1c4e8364 Kostas Papadimitriou
    url = "%s?%s" % (authenticate_url, urllib.urlencode(params))
107 c101b32b Kostas Papadimitriou
    return HttpResponseRedirect(url)
108 c101b32b Kostas Papadimitriou
109 c101b32b Kostas Papadimitriou
110 c101b32b Kostas Papadimitriou
@requires_auth_provider('twitter', login=True)
111 c101b32b Kostas Papadimitriou
@require_http_methods(["GET", "POST"])
112 222305b7 Sofia Papagiannaki
@cookie_fix
113 8fb8d0cf Giorgos Korfiatis
def authenticated(request,
114 8fb8d0cf Giorgos Korfiatis
                  template='im/third_party_check_local.html',
115 8fb8d0cf Giorgos Korfiatis
                  extra_context=None):
116 7beef200 Kostas Papadimitriou
117 7beef200 Kostas Papadimitriou
    if extra_context is None:
118 7beef200 Kostas Papadimitriou
        extra_context = {}
119 c101b32b Kostas Papadimitriou
120 9d20fe23 Kostas Papadimitriou
    consumer = oauth.Consumer(settings.TWITTER_TOKEN,
121 9d20fe23 Kostas Papadimitriou
                              settings.TWITTER_SECRET)
122 9d20fe23 Kostas Papadimitriou
    client = oauth.Client(consumer)
123 9d20fe23 Kostas Papadimitriou
124 1c4e8364 Kostas Papadimitriou
    if request.GET.get('denied'):
125 1c4e8364 Kostas Papadimitriou
        return HttpResponseRedirect(reverse('edit_profile'))
126 1c4e8364 Kostas Papadimitriou
127 c101b32b Kostas Papadimitriou
    if not 'request_token' in request.session:
128 c101b32b Kostas Papadimitriou
        messages.error(request, 'Twitter handshake failed')
129 c101b32b Kostas Papadimitriou
        return HttpResponseRedirect(reverse('edit_profile'))
130 c101b32b Kostas Papadimitriou
131 c101b32b Kostas Papadimitriou
    token = oauth.Token(request.session['request_token']['oauth_token'],
132 8fb8d0cf Giorgos Korfiatis
                        request.session['request_token']['oauth_token_secret'])
133 c101b32b Kostas Papadimitriou
    client = oauth.Client(consumer, token)
134 c101b32b Kostas Papadimitriou
135 c101b32b Kostas Papadimitriou
    # Step 2. Request the authorized access token from Twitter.
136 29576723 Sofia Papagiannaki
    parts = list(urlsplit(access_token_url))
137 29576723 Sofia Papagiannaki
    params = dict(parse_qsl(parts[3], keep_blank_values=True))
138 29576723 Sofia Papagiannaki
    oauth_verifier = request.GET.get('oauth_verifier')
139 29576723 Sofia Papagiannaki
    params['oauth_verifier'] = oauth_verifier
140 29576723 Sofia Papagiannaki
    parts[3] = urlencode(params)
141 29576723 Sofia Papagiannaki
    parameterized_url = urlunsplit(parts)
142 29576723 Sofia Papagiannaki
143 29576723 Sofia Papagiannaki
    resp, content = client.request(parameterized_url, "GET")
144 29576723 Sofia Papagiannaki
145 c101b32b Kostas Papadimitriou
    if resp['status'] != '200':
146 c101b32b Kostas Papadimitriou
        try:
147 1c4e8364 Kostas Papadimitriou
            del request.session['request_token']
148 c101b32b Kostas Papadimitriou
        except:
149 1c4e8364 Kostas Papadimitriou
            pass
150 c101b32b Kostas Papadimitriou
        messages.error(request, 'Invalid Twitter response')
151 e6d8c1c0 Kostas Papadimitriou
        logger.error("Invalid twitter response %s", resp)
152 c101b32b Kostas Papadimitriou
        return HttpResponseRedirect(reverse('edit_profile'))
153 c101b32b Kostas Papadimitriou
154 c101b32b Kostas Papadimitriou
    access_token = dict(cgi.parse_qsl(content))
155 c101b32b Kostas Papadimitriou
    userid = access_token['user_id']
156 3a72a5d4 Kostas Papadimitriou
    username = access_token.get('screen_name', userid)
157 c630fee6 Kostas Papadimitriou
    provider_info = {'screen_name': username}
158 c630fee6 Kostas Papadimitriou
    affiliation = 'Twitter.com'
159 c101b32b Kostas Papadimitriou
160 c101b32b Kostas Papadimitriou
    try:
161 0e79735c Kostas Papadimitriou
        return handle_third_party_login(request, 'twitter', userid,
162 c8d89a3c Kostas Papadimitriou
                                        provider_info, affiliation)
163 c101b32b Kostas Papadimitriou
    except AstakosUser.DoesNotExist, e:
164 c8d89a3c Kostas Papadimitriou
        third_party_key = get_pending_key(request)
165 dd5f8f4d Kostas Papadimitriou
        user_info = {'affiliation': affiliation}
166 dd5f8f4d Kostas Papadimitriou
        return handle_third_party_signup(request, userid, 'twitter',
167 dd5f8f4d Kostas Papadimitriou
                                         third_party_key,
168 dd5f8f4d Kostas Papadimitriou
                                         provider_info,
169 dd5f8f4d Kostas Papadimitriou
                                         user_info,
170 dd5f8f4d Kostas Papadimitriou
                                         template,
171 dd5f8f4d Kostas Papadimitriou
                                         extra_context)