· 9 years ago · Oct 19, 2016, 02:34 AM
1# !/usr/bin/env python
2# -*- coding: utf-8 -*-
3__author__ = 'Diego Garcia'
4
5import tornado.web
6import tornado.ioloop
7import oauth2.tokengenerator
8import oauth2.grant
9import oauth2.store.redisdb
10import oauth2.store.mongodb
11import json
12import time
13import fakeredis
14import mongomock
15
16
17class OAuth2Handler(tornado.web.RequestHandler):
18 # Generator of tokens (with client authentications)
19 def initialize(self, controller):
20 self.controller = controller
21
22 def post(self):
23 response = self._dispatch_request()
24
25 self._map_response(response)
26
27 def _dispatch_request(self):
28 request = self.request
29 request.post_param = lambda key: json.loads(request.body.decode())[key]
30
31 return self.controller.dispatch(request, environ={})
32
33 def _map_response(self, response):
34 for name, value in list(response.headers.items()):
35 self.set_header(name, value)
36
37 self.set_status(response.status_code)
38 self.write(response.body)
39
40
41class BaseHandler(tornado.web.RequestHandler):
42 def initialize(self, controller):
43 self.controller = controller
44
45 # authenticate tokens
46 def prepare(self):
47 try:
48 token = self.get_argument('access_token', None)
49 if not token:
50 auth_header = self.request.headers.get('Authorization', None)
51 if not auth_header:
52 raise Exception('This resource need a authorization token')
53 token = auth_header[7:]
54
55 key = 'oauth2_{}'.format(token)
56 access = self.controller.access_token_store.rs.get(key)
57 if access:
58 access = json.loads(access.decode())
59 else:
60 raise Exception('Invalid Token')
61 if access['expires_at'] <= int(time.time()):
62 raise Exception('expired token')
63 except Exception as err:
64 self.set_header('Content-Type', 'application/json')
65 self.set_status(401)
66 self.finish(json.dumps({'error': str(err)}))
67
68
69class FooHandler(BaseHandler):
70 def get(self):
71 self.finish(json.dumps({'msg': 'This is Foo!'}))
72
73
74def main():
75 # Populate mock
76 mongo = mongomock.MongoClient()
77 mongo['db']['oauth_clients'].insert({'identifier': 'abc',
78 'secret': 'xyz',
79 'redirect_uris': [],
80 'authorized_grants': [oauth2.grant.ClientCredentialsGrant.grant_type]})
81 # MongoDB for clients store
82 client_store = oauth2.store.mongodb.ClientStore(mongo['db']['oauth_clients'])
83
84 # Redis for tokens storage
85 token_store = oauth2.store.redisdb.TokenStore(rs=fakeredis.FakeStrictRedis())
86
87 # Generator of tokens
88 token_generator = oauth2.tokengenerator.Uuid4()
89 token_generator.expires_in[oauth2.grant.ClientCredentialsGrant.grant_type] = 3600
90
91 # OAuth2 controller
92 auth_controller = oauth2.Provider(
93 access_token_store=token_store,
94 auth_code_store=token_store,
95 client_store=client_store,
96 site_adapter=None,
97 token_generator=token_generator
98 )
99 auth_controller.token_path = '/oauth/token'
100
101
102 # Add Client Credentials to OAuth2 controller
103 auth_controller.add_grant(oauth2.grant.ClientCredentialsGrant())
104
105 # Create Tornado application
106 app = tornado.web.Application([
107 (r'/oauth/token', OAuth2Handler, dict(controller=auth_controller)),
108 (r'/foo', FooHandler, dict(controller=auth_controller))
109 ])
110
111 # Start Server
112 app.listen(8889)
113 print("Server Starting")
114 tornado.ioloop.IOLoop.instance().start()
115
116if __name__ == "__main__":
117 main()