Statistics
| Branch: | Tag: | Revision:

root / pithos / im / target / twitter.py @ 552ea518

History | View | Annotate | Download (4.9 kB)

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