Statistics
| Branch: | Tag: | Revision:

root / astakos / im / target / twitter.py @ 890b0eaf

History | View | Annotate | Download (5.2 kB)

1 64cd4730 Antony Chazapis
# Copyright 2011 GRNET S.A. All rights reserved.
2 64cd4730 Antony Chazapis
# 
3 64cd4730 Antony Chazapis
# Redistribution and use in source and binary forms, with or
4 64cd4730 Antony Chazapis
# without modification, are permitted provided that the following
5 64cd4730 Antony Chazapis
# conditions are met:
6 64cd4730 Antony Chazapis
# 
7 64cd4730 Antony Chazapis
#   1. Redistributions of source code must retain the above
8 64cd4730 Antony Chazapis
#      copyright notice, this list of conditions and the following
9 64cd4730 Antony Chazapis
#      disclaimer.
10 64cd4730 Antony Chazapis
# 
11 64cd4730 Antony Chazapis
#   2. Redistributions in binary form must reproduce the above
12 64cd4730 Antony Chazapis
#      copyright notice, this list of conditions and the following
13 64cd4730 Antony Chazapis
#      disclaimer in the documentation and/or other materials
14 64cd4730 Antony Chazapis
#      provided with the distribution.
15 64cd4730 Antony Chazapis
# 
16 64cd4730 Antony Chazapis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 64cd4730 Antony Chazapis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 64cd4730 Antony Chazapis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 64cd4730 Antony Chazapis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 64cd4730 Antony Chazapis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 64cd4730 Antony Chazapis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 64cd4730 Antony Chazapis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 64cd4730 Antony Chazapis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 64cd4730 Antony Chazapis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 64cd4730 Antony Chazapis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 64cd4730 Antony Chazapis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 64cd4730 Antony Chazapis
# POSSIBILITY OF SUCH DAMAGE.
28 64cd4730 Antony Chazapis
# 
29 64cd4730 Antony Chazapis
# The views and conclusions contained in the software and
30 64cd4730 Antony Chazapis
# documentation are those of the authors and should not be
31 64cd4730 Antony Chazapis
# interpreted as representing official policies, either expressed
32 64cd4730 Antony Chazapis
# or implied, of GRNET S.A.
33 64cd4730 Antony Chazapis
34 64cd4730 Antony Chazapis
# This is based on the docs at: https://github.com/simplegeo/python-oauth2
35 64cd4730 Antony Chazapis
36 64cd4730 Antony Chazapis
import oauth2 as oauth
37 64cd4730 Antony Chazapis
import urlparse
38 64cd4730 Antony Chazapis
39 64cd4730 Antony Chazapis
from django.conf import settings
40 64cd4730 Antony Chazapis
from django.http import HttpResponse
41 64cd4730 Antony Chazapis
from django.utils import simplejson as json
42 890b0eaf Sofia Papagiannaki
from django.contrib.auth import authenticate
43 64cd4730 Antony Chazapis
44 0905ccd2 Sofia Papagiannaki
from astakos.im.target.util import prepare_response
45 0905ccd2 Sofia Papagiannaki
from astakos.im.util import get_or_create_user
46 64cd4730 Antony Chazapis
47 64cd4730 Antony Chazapis
# It's probably a good idea to put your consumer's OAuth token and
48 64cd4730 Antony Chazapis
# OAuth secret into your project's settings. 
49 64cd4730 Antony Chazapis
consumer = oauth.Consumer(settings.TWITTER_KEY, settings.TWITTER_SECRET)
50 64cd4730 Antony Chazapis
client = oauth.Client(consumer)
51 64cd4730 Antony Chazapis
52 64cd4730 Antony Chazapis
request_token_url = 'http://twitter.com/oauth/request_token'
53 64cd4730 Antony Chazapis
access_token_url = 'http://twitter.com/oauth/access_token'
54 64cd4730 Antony Chazapis
55 64cd4730 Antony Chazapis
# This is the slightly different URL used to authenticate/authorize.
56 64cd4730 Antony Chazapis
authenticate_url = 'http://twitter.com/oauth/authenticate'
57 64cd4730 Antony Chazapis
58 64cd4730 Antony Chazapis
def login(request):
59 64cd4730 Antony Chazapis
    # Step 1. Get a request token from Twitter.
60 64cd4730 Antony Chazapis
    resp, content = client.request(request_token_url, "GET")
61 64cd4730 Antony Chazapis
    if resp['status'] != '200':
62 64cd4730 Antony Chazapis
        raise Exception("Invalid response from Twitter.")
63 64cd4730 Antony Chazapis
    request_token = dict(urlparse.parse_qsl(content))
64 64cd4730 Antony Chazapis
    if request.GET.get('next'):
65 64cd4730 Antony Chazapis
        request_token['next'] = request.GET['next']
66 64cd4730 Antony Chazapis
    
67 64cd4730 Antony Chazapis
    # Step 2. Store the request token in a session for later use.
68 64cd4730 Antony Chazapis
    response = HttpResponse()
69 64cd4730 Antony Chazapis
    response.set_cookie('Twitter-Request-Token', value=json.dumps(request_token), max_age=300)
70 64cd4730 Antony Chazapis
    
71 64cd4730 Antony Chazapis
    # Step 3. Redirect the user to the authentication URL.
72 64cd4730 Antony Chazapis
    url = "%s?oauth_token=%s" % (authenticate_url, request_token['oauth_token'])
73 64cd4730 Antony Chazapis
    response['Location'] = url
74 64cd4730 Antony Chazapis
    response.status_code = 302
75 64cd4730 Antony Chazapis
    
76 64cd4730 Antony Chazapis
    return response
77 64cd4730 Antony Chazapis
78 64cd4730 Antony Chazapis
def authenticated(request):
79 64cd4730 Antony Chazapis
    # Step 1. Use the request token in the session to build a new client.
80 64cd4730 Antony Chazapis
    data = request.COOKIES.get('Twitter-Request-Token', None)
81 64cd4730 Antony Chazapis
    if not data:
82 64cd4730 Antony Chazapis
        raise Exception("Request token cookie not found.")
83 64cd4730 Antony Chazapis
    request_token = json.loads(data)
84 64cd4730 Antony Chazapis
    if not hasattr(request_token, '__getitem__'):
85 64cd4730 Antony Chazapis
        raise BadRequest('Invalid data formating')
86 64cd4730 Antony Chazapis
    try:
87 64cd4730 Antony Chazapis
        token = oauth.Token(request_token['oauth_token'],
88 64cd4730 Antony Chazapis
                            request_token['oauth_token_secret'])
89 64cd4730 Antony Chazapis
    except:
90 64cd4730 Antony Chazapis
        raise BadRequest('Invalid request token cookie formatting')
91 64cd4730 Antony Chazapis
    client = oauth.Client(consumer, token)
92 64cd4730 Antony Chazapis
    
93 64cd4730 Antony Chazapis
    # Step 2. Request the authorized access token from Twitter.
94 64cd4730 Antony Chazapis
    resp, content = client.request(access_token_url, "GET")
95 64cd4730 Antony Chazapis
    if resp['status'] != '200':
96 64cd4730 Antony Chazapis
        raise Exception("Invalid response from Twitter.")
97 64cd4730 Antony Chazapis
    
98 64cd4730 Antony Chazapis
    """
99 64cd4730 Antony Chazapis
    This is what you'll get back from Twitter. Note that it includes the
100 64cd4730 Antony Chazapis
    user's user_id and screen_name.
101 64cd4730 Antony Chazapis
    {
102 64cd4730 Antony Chazapis
        'oauth_token_secret': 'IcJXPiJh8be3BjDWW50uCY31chyhsMHEhqJVsphC3M',
103 64cd4730 Antony Chazapis
        'user_id': '120889797', 
104 64cd4730 Antony Chazapis
        'oauth_token': '120889797-H5zNnM3qE0iFoTTpNEHIz3noL9FKzXiOxwtnyVOD',
105 64cd4730 Antony Chazapis
        'screen_name': 'heyismysiteup'
106 64cd4730 Antony Chazapis
    }
107 64cd4730 Antony Chazapis
    """
108 64cd4730 Antony Chazapis
    access_token = dict(urlparse.parse_qsl(content))
109 64cd4730 Antony Chazapis
    
110 64cd4730 Antony Chazapis
    # Step 3. Lookup the user or create them if they don't exist.
111 64cd4730 Antony Chazapis
    
112 64cd4730 Antony Chazapis
    # When creating the user I just use their screen_name@twitter.com
113 64cd4730 Antony Chazapis
    # for their email and the oauth_token_secret for their password.
114 64cd4730 Antony Chazapis
    # These two things will likely never be used. Alternatively, you 
115 64cd4730 Antony Chazapis
    # can prompt them for their email here. Either way, the password 
116 64cd4730 Antony Chazapis
    # should never be used.
117 0905ccd2 Sofia Papagiannaki
    username = '%s@twitter.com' % access_token['screen_name']
118 890b0eaf Sofia Papagiannaki
    realname = access_token['screen_name']
119 64cd4730 Antony Chazapis
    
120 890b0eaf Sofia Papagiannaki
    user = get_or_create_user(username, realname=realname, affiliation='Twitter', level=0, email=username)
121 890b0eaf Sofia Papagiannaki
    # in order to login the user we must call authenticate first
122 890b0eaf Sofia Papagiannaki
    user = authenticate(username=user.username, auth_token=user.auth_token)
123 64cd4730 Antony Chazapis
    return prepare_response(request,
124 890b0eaf Sofia Papagiannaki
                            user,
125 64cd4730 Antony Chazapis
                            request_token.get('next'))