Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (6 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 c630fee6 Kostas Papadimitriou
import json
35 c8d89a3c Kostas Papadimitriou
import logging
36 c630fee6 Kostas Papadimitriou
37 c101b32b Kostas Papadimitriou
from django.http import HttpResponseBadRequest
38 c101b32b Kostas Papadimitriou
from django.utils.translation import ugettext as _
39 c101b32b Kostas Papadimitriou
from django.contrib import messages
40 c101b32b Kostas Papadimitriou
from django.template import RequestContext
41 c101b32b Kostas Papadimitriou
from django.views.decorators.http import require_http_methods
42 c101b32b Kostas Papadimitriou
from django.http import HttpResponseRedirect
43 c101b32b Kostas Papadimitriou
from django.core.urlresolvers import reverse
44 c101b32b Kostas Papadimitriou
from django.core.exceptions import ImproperlyConfigured
45 c101b32b Kostas Papadimitriou
from django.shortcuts import get_object_or_404
46 c101b32b Kostas Papadimitriou
47 c101b32b Kostas Papadimitriou
from urlparse import urlunsplit, urlsplit
48 c101b32b Kostas Papadimitriou
49 dd5f8f4d Kostas Papadimitriou
from astakos.im.util import prepare_response, get_context, login_url
50 c101b32b Kostas Papadimitriou
from astakos.im.views import requires_anonymous, render_response, \
51 63836eda Kostas Papadimitriou
        requires_auth_provider, required_auth_methods_assigned
52 c101b32b Kostas Papadimitriou
from astakos.im.settings import ENABLE_LOCAL_ACCOUNT_MIGRATION, BASEURL
53 c101b32b Kostas Papadimitriou
from astakos.im.models import AstakosUser, PendingThirdPartyUser
54 c101b32b Kostas Papadimitriou
from astakos.im.forms import LoginForm
55 c101b32b Kostas Papadimitriou
from astakos.im.activation_backends import get_backend, SimpleBackend
56 c101b32b Kostas Papadimitriou
from astakos.im import settings
57 c630fee6 Kostas Papadimitriou
from astakos.im import auth_providers
58 dd5f8f4d Kostas Papadimitriou
from astakos.im.target import add_pending_auth_provider, get_pending_key, \
59 0e79735c Kostas Papadimitriou
    handle_third_party_signup, handle_third_party_login, init_third_party_session
60 c101b32b Kostas Papadimitriou
61 c101b32b Kostas Papadimitriou
import astakos.im.messages as astakos_messages
62 c101b32b Kostas Papadimitriou
63 c101b32b Kostas Papadimitriou
64 c101b32b Kostas Papadimitriou
logger = logging.getLogger(__name__)
65 c101b32b Kostas Papadimitriou
66 c101b32b Kostas Papadimitriou
import oauth2 as oauth
67 c101b32b Kostas Papadimitriou
import cgi
68 1c4e8364 Kostas Papadimitriou
import urllib
69 c101b32b Kostas Papadimitriou
70 c101b32b Kostas Papadimitriou
consumer = oauth.Consumer(settings.TWITTER_TOKEN, settings.TWITTER_SECRET)
71 c101b32b Kostas Papadimitriou
client = oauth.Client(consumer)
72 c101b32b Kostas Papadimitriou
73 c101b32b Kostas Papadimitriou
request_token_url = 'http://twitter.com/oauth/request_token'
74 c101b32b Kostas Papadimitriou
access_token_url = 'http://twitter.com/oauth/access_token'
75 c101b32b Kostas Papadimitriou
authenticate_url = 'http://twitter.com/oauth/authenticate'
76 c101b32b Kostas Papadimitriou
77 c101b32b Kostas Papadimitriou
@requires_auth_provider('twitter', login=True)
78 c101b32b Kostas Papadimitriou
@require_http_methods(["GET", "POST"])
79 c101b32b Kostas Papadimitriou
def login(request):
80 0e79735c Kostas Papadimitriou
    init_third_party_session(request)
81 1c4e8364 Kostas Papadimitriou
    force_login = request.GET.get('force_login',
82 1c4e8364 Kostas Papadimitriou
                                  settings.TWITTER_AUTH_FORCE_LOGIN)
83 c101b32b Kostas Papadimitriou
    resp, content = client.request(request_token_url, "GET")
84 c101b32b Kostas Papadimitriou
    if resp['status'] != '200':
85 c101b32b Kostas Papadimitriou
        messages.error(request, 'Invalid Twitter response')
86 c101b32b Kostas Papadimitriou
        return HttpResponseRedirect(reverse('edit_profile'))
87 c101b32b Kostas Papadimitriou
88 c101b32b Kostas Papadimitriou
    request.session['request_token'] = dict(cgi.parse_qsl(content))
89 1c4e8364 Kostas Papadimitriou
    params = {
90 1c4e8364 Kostas Papadimitriou
        'oauth_token': request.session['request_token']['oauth_token'],
91 1c4e8364 Kostas Papadimitriou
    }
92 1c4e8364 Kostas Papadimitriou
    if force_login:
93 1c4e8364 Kostas Papadimitriou
        params['force_login'] = 1
94 1c4e8364 Kostas Papadimitriou
95 dd5f8f4d Kostas Papadimitriou
    if request.GET.get('key', None):
96 dd5f8f4d Kostas Papadimitriou
        request.session['pending_key'] = request.GET.get('key')
97 dd5f8f4d Kostas Papadimitriou
98 64492c49 Kostas Papadimitriou
    if request.GET.get('next', None):
99 64492c49 Kostas Papadimitriou
        request.session['next_url'] = request.GET.get('next')
100 dd5f8f4d Kostas Papadimitriou
101 1c4e8364 Kostas Papadimitriou
    url = "%s?%s" % (authenticate_url, urllib.urlencode(params))
102 c101b32b Kostas Papadimitriou
    return HttpResponseRedirect(url)
103 c101b32b Kostas Papadimitriou
104 c101b32b Kostas Papadimitriou
105 c101b32b Kostas Papadimitriou
@requires_auth_provider('twitter', login=True)
106 c101b32b Kostas Papadimitriou
@require_http_methods(["GET", "POST"])
107 c101b32b Kostas Papadimitriou
def authenticated(
108 c101b32b Kostas Papadimitriou
    request,
109 c101b32b Kostas Papadimitriou
    template='im/third_party_check_local.html',
110 73fbaec4 Sofia Papagiannaki
    extra_context={}):
111 c101b32b Kostas Papadimitriou
112 64492c49 Kostas Papadimitriou
    next_url = None
113 64492c49 Kostas Papadimitriou
    if 'next_url' in request.session:
114 64492c49 Kostas Papadimitriou
        next_url = request.session['next_url']
115 64492c49 Kostas Papadimitriou
        del request.session['next_url']
116 64492c49 Kostas Papadimitriou
117 1c4e8364 Kostas Papadimitriou
    if request.GET.get('denied'):
118 1c4e8364 Kostas Papadimitriou
        return HttpResponseRedirect(reverse('edit_profile'))
119 1c4e8364 Kostas Papadimitriou
120 c101b32b Kostas Papadimitriou
    if not 'request_token' in request.session:
121 c101b32b Kostas Papadimitriou
        messages.error(request, 'Twitter handshake failed')
122 c101b32b Kostas Papadimitriou
        return HttpResponseRedirect(reverse('edit_profile'))
123 c101b32b Kostas Papadimitriou
124 c101b32b Kostas Papadimitriou
    token = oauth.Token(request.session['request_token']['oauth_token'],
125 c101b32b Kostas Papadimitriou
        request.session['request_token']['oauth_token_secret'])
126 c101b32b Kostas Papadimitriou
    client = oauth.Client(consumer, token)
127 c101b32b Kostas Papadimitriou
128 c101b32b Kostas Papadimitriou
    # Step 2. Request the authorized access token from Twitter.
129 c101b32b Kostas Papadimitriou
    resp, content = client.request(access_token_url, "GET")
130 c101b32b Kostas Papadimitriou
    if resp['status'] != '200':
131 c101b32b Kostas Papadimitriou
        try:
132 1c4e8364 Kostas Papadimitriou
            del request.session['request_token']
133 c101b32b Kostas Papadimitriou
        except:
134 1c4e8364 Kostas Papadimitriou
            pass
135 c101b32b Kostas Papadimitriou
        messages.error(request, 'Invalid Twitter response')
136 c101b32b Kostas Papadimitriou
        return HttpResponseRedirect(reverse('edit_profile'))
137 c101b32b Kostas Papadimitriou
138 c101b32b Kostas Papadimitriou
    access_token = dict(cgi.parse_qsl(content))
139 c101b32b Kostas Papadimitriou
    userid = access_token['user_id']
140 3a72a5d4 Kostas Papadimitriou
    username = access_token.get('screen_name', userid)
141 c630fee6 Kostas Papadimitriou
    provider_info = {'screen_name': username}
142 c630fee6 Kostas Papadimitriou
    affiliation = 'Twitter.com'
143 c101b32b Kostas Papadimitriou
144 c101b32b Kostas Papadimitriou
145 c101b32b Kostas Papadimitriou
    try:
146 0e79735c Kostas Papadimitriou
        return handle_third_party_login(request, 'twitter', userid,
147 c8d89a3c Kostas Papadimitriou
                                        provider_info, affiliation)
148 c101b32b Kostas Papadimitriou
    except AstakosUser.DoesNotExist, e:
149 c8d89a3c Kostas Papadimitriou
        third_party_key = get_pending_key(request)
150 dd5f8f4d Kostas Papadimitriou
        user_info = {'affiliation': affiliation}
151 dd5f8f4d Kostas Papadimitriou
        return handle_third_party_signup(request, userid, 'twitter',
152 dd5f8f4d Kostas Papadimitriou
                                         third_party_key,
153 dd5f8f4d Kostas Papadimitriou
                                         provider_info,
154 dd5f8f4d Kostas Papadimitriou
                                         user_info,
155 dd5f8f4d Kostas Papadimitriou
                                         template,
156 dd5f8f4d Kostas Papadimitriou
                                         extra_context)