-
Notifications
You must be signed in to change notification settings - Fork 10
/
main.py
144 lines (116 loc) · 4.48 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#!/usr/bin/python
import Cookie
import email.utils
import logging
import os
import time
try: import simplejson as json
except ImportError: import json
from foursquare import InvalidAuth
from config import CONFIG, APP_CLASS
from foursquare_secrets import SECRETS
from model import UserSession, UserToken
import utils
from google.appengine.api import taskqueue
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext.webapp import template
class OAuthConnectErrorException(Exception):
pass
class OAuthConnectDeniedException(Exception):
pass
class OAuth(webapp.RequestHandler):
"""Handle the OAuth redirect back to the service."""
def post(self):
self.get()
def get(self):
try:
error = self.request.get('error')
if error == "access_denied":
raise OAuthConnectDeniedException
elif error:
raise OAuthConnectErrorException
code = self.request.get('code')
if not code:
raise OAuthConnectErrorException
client = utils.makeFoursquareClient()
access_token = client.oauth.get_token(code)
if not access_token:
raise OAuthConnectErrorException
client.set_access_token(access_token)
except OAuthConnectDeniedException:
self.redirect(CONFIG['auth_denied_uri'])
return
except OAuthConnectErrorException:
path = os.path.join(os.path.dirname(__file__),
'templates/connect_error.html')
self.response.out.write(template.render(path, {'name': CONFIG['site_name']}))
return
user = client.users() # returns the auth'd users info
fs_user_id = user['user']['id']
existing_token = UserToken.get_by_fs_id(fs_user_id)
if existing_token:
token = existing_token
else:
token = UserToken()
token.token = access_token
token.fs_id = fs_user_id
token.put()
session = UserSession.get_or_create_session(fs_user_id)
cookie = Cookie.SimpleCookie()
cookie['session'] = session.session
cookie['session']['path'] = '/'
cookie['session']['expires'] = email.utils.formatdate(time.time() + (14 * 86400), localtime=False, usegmt=True)
self.response.headers.add_header("Set-Cookie", cookie.output()[12:])
isMobile = utils.isMobileUserAgent(self.request.headers['User-Agent'])
redirect_uri = CONFIG['auth_success_uri_mobile'] if isMobile else CONFIG['auth_success_uri_desktop']
self.redirect(redirect_uri)
class IsAuthd(webapp.RequestHandler):
"""Returns whether or not a user has connected their foursquare account"""
def get(self):
user_token = UserToken.get_from_cookie(self.request.cookies.get('session', None))
is_authd = 'false'
if user_token and user_token.fs_id:
client = utils.makeFoursquareClient(user_token.token)
try:
client.users()
is_authd = 'true'
except InvalidAuth:
user_token.delete()
self.response.out.write(is_authd)
class ProcessCheckin(webapp.RequestHandler):
PREFIX = "/checkin"
def post(self):
# Validate against our push secret if we're not in local_dev mode.
if (self.request.get('secret') != SECRETS['push_secret'] and not CONFIG['local_dev']):
self.error = 403
return
checkin_json = json.loads(self.request.get('checkin'),
parse_float=str)
if 'venue' not in checkin_json:
# stupid shouts. skip everything
return
logging.debug('received checkin ' + checkin_json['id'])
taskqueue.add(url='/_checkin',
params={'checkin': self.request.get('checkin')})
class HomePage(webapp.RequestHandler):
def get(self):
client_id = CONFIG['client_id']
params = {'client_id': client_id}
params['auth_url'] = utils.generateFoursquareAuthUri(client_id)
params['name'] = CONFIG['site_name']
params['description'] = CONFIG['site_description']
path = os.path.join(os.path.dirname(__file__),
'templates/index.html')
self.response.out.write(template.render(path, params))
application = webapp.WSGIApplication([('/oauth.*', OAuth),
('/checkin', ProcessCheckin),
('/isAuthd', IsAuthd),
('/', HomePage),
('/_checkin', APP_CLASS),
('/.*', APP_CLASS)],
debug=CONFIG['debug'])
def main():
run_wsgi_app(application)
if __name__ == "__main__":
main()