Statistics
| Branch: | Tag: | Revision:

root / astakos / im / target / twitter.py @ 7d7f1f1b

History | View | Annotate | Download (5.2 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
# This is based on the docs at: https://github.com/simplegeo/python-oauth2
35

    
36
import oauth2 as oauth
37
import urlparse
38
import uuid
39

    
40
from django.conf import settings
41
from django.http import HttpResponse
42
from django.utils import simplejson as json
43
from django.contrib.auth import authenticate
44

    
45
from astakos.im.target.util import prepare_response
46
from astakos.im.util import get_or_create_user
47

    
48
# It's probably a good idea to put your consumer's OAuth token and
49
# OAuth secret into your project's settings. 
50
consumer = oauth.Consumer(settings.TWITTER_KEY, settings.TWITTER_SECRET)
51
client = oauth.Client(consumer)
52

    
53
request_token_url = 'http://twitter.com/oauth/request_token'
54
access_token_url = 'http://twitter.com/oauth/access_token'
55

    
56
# This is the slightly different URL used to authenticate/authorize.
57
authenticate_url = 'http://twitter.com/oauth/authenticate'
58

    
59
def login(request):
60
    # Step 1. Get a request token from Twitter.
61
    resp, content = client.request(request_token_url, "GET")
62
    if resp['status'] != '200':
63
        raise Exception("Invalid response from Twitter.")
64
    request_token = dict(urlparse.parse_qsl(content))
65
    if request.GET.get('next'):
66
        request_token['next'] = request.GET['next']
67
    
68
    # Step 2. Store the request token in a session for later use.
69
    response = HttpResponse()
70
    response.set_cookie('Twitter-Request-Token', value=json.dumps(request_token), max_age=300)
71
    
72
    # Step 3. Redirect the user to the authentication URL.
73
    url = "%s?oauth_token=%s" % (authenticate_url, request_token['oauth_token'])
74
    response['Location'] = url
75
    response.status_code = 302
76
    
77
    return response
78

    
79
def authenticated(request):
80
    # Step 1. Use the request token in the session to build a new client.
81
    data = request.COOKIES.get('Twitter-Request-Token', None)
82
    if not data:
83
        raise Exception("Request token cookie not found.")
84
    request_token = json.loads(data)
85
    if not hasattr(request_token, '__getitem__'):
86
        raise BadRequest('Invalid data formating')
87
    try:
88
        token = oauth.Token(request_token['oauth_token'],
89
                            request_token['oauth_token_secret'])
90
    except:
91
        raise BadRequest('Invalid request token cookie formatting')
92
    client = oauth.Client(consumer, token)
93
    
94
    # Step 2. Request the authorized access token from Twitter.
95
    resp, content = client.request(access_token_url, "GET")
96
    if resp['status'] != '200':
97
        raise Exception("Invalid response from Twitter.")
98
    
99
    """
100
    This is what you'll get back from Twitter. Note that it includes the
101
    user's user_id and screen_name.
102
    {
103
        'oauth_token_secret': 'IcJXPiJh8be3BjDWW50uCY31chyhsMHEhqJVsphC3M',
104
        'user_id': '120889797', 
105
        'oauth_token': '120889797-H5zNnM3qE0iFoTTpNEHIz3noL9FKzXiOxwtnyVOD',
106
        'screen_name': 'heyismysiteup'
107
    }
108
    """
109
    access_token = dict(urlparse.parse_qsl(content))
110
    
111
    # Step 3. Lookup the user or create them if they don't exist.
112
    
113
    # When creating the user I just use their screen_name@twitter.com
114
    # for their email and the oauth_token_secret for their password.
115
    # These two things will likely never be used. Alternatively, you 
116
    # can prompt them for their email here. Either way, the password 
117
    # should never be used.
118
    email = '%s@twitter.com' % access_token['screen_name']
119
    realname = access_token['screen_name']
120
    username = uuid.uuid4().hex[:30]
121
    user = get_or_create_user(username, realname=realname, affiliation='Twitter', level=0, email=email)
122
    # in order to login the user we must call authenticate first
123
    user = authenticate(email=user.email, auth_token=user.auth_token)
124
    return prepare_response(request,
125
                            user,
126
                            request_token.get('next'))