1
1
# coding: utf-8
2
2
"""
3
- flask_oauthlib.contrib.bindings
4
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3
+ flask_oauthlib.contrib.oauth2
4
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6
6
SQLAlchemy and Grant-Caching for OAuth2 provider.
7
7
8
8
contributed by: Randy Topliffe
9
9
"""
10
10
11
- from datetime import datetime , timedelta
12
- from werkzeug .contrib .cache import (
13
- NullCache ,
14
- SimpleCache ,
15
- MemcachedCache ,
16
- RedisCache ,
17
- FileSystemCache
18
- )
19
11
import logging
12
+ from datetime import datetime , timedelta
13
+ from .cache import Cache
20
14
21
15
22
16
__all__ = ('GrantCacheBinding' , 'SQLAlchemyBinding' )
@@ -60,11 +54,7 @@ def delete(self):
60
54
@property
61
55
def key (self ):
62
56
"""The string used as the key for the cache"""
63
- key = '{code}{client_id}' .format (
64
- code = self .code ,
65
- client_id = self .client_id
66
- )
67
- return key
57
+ return '%s%s' % (self .code , self .client_id )
68
58
69
59
def __getitem__ (self , item ):
70
60
return getattr (self , item )
@@ -73,187 +63,35 @@ def keys(self):
73
63
return ['client_id' , 'code' , 'redirect_uri' , 'scopes' , 'user' ]
74
64
75
65
76
- class GrantCacheBinding (object ):
77
- """Configures an :class:`OAuth2Provider` instance to use various caching
78
- systems to get and set the grant token. This removes the need to
79
- register :func:`grantgetter` and :func:`grantsetter` yourself.
80
-
81
- :param app: Flask application instance
82
- :param provider: :class:`OAuth2Provider` instance
83
- :param current_user: function that returns an :class:`User` object
84
- :param config: Additional configuration
85
-
86
- A usage example::
87
-
88
- oauth = OAuth2Provider(app)
89
- config = {'OAUTH2_CACHE_TYPE': 'redis'}
90
-
91
- GrantCacheBinding(app, oauth, current_user, config=config)
92
-
93
- You can define which cache system you would like to use by setting the
94
- following configuration option::
95
-
96
- OAUTH2_CACHE_TYPE = 'null' // memcache, simple, redis, filesystem
97
-
98
- For more information on the supported cache systems please visit:
99
- `Cache <http://werkzeug.pocoo.org/docs/contrib/cache/>`_
100
-
101
- """
66
+ def grant_cache_binding (app , provider , current_user ):
67
+ cache = Cache (app , 'OAUTH2' )
102
68
103
- def __init__ (self , app , provider , current_user , config = None ):
104
-
105
- if config is None :
106
- config = app .config
107
- else :
108
- from itertools import chain
109
- config = dict (chain (app .config .items (), config .items ()))
110
-
111
- self .current_user = current_user
112
-
113
- settings = (
114
- {
115
- 'flask_oauthlib_key' : 'OAUTH2_CACHE_DEFAULT_TIMEOUT' ,
116
- 'flask_cache_key' : 'CACHE_DEFAULT_TIMEOUT' ,
117
- 'default_value' : 100
118
- },
119
- {
120
- 'flask_oauthlib_key' : 'OAUTH2_CACHE_THRESHOLD' ,
121
- 'flask_cache_key' : 'CACHE_THRESHOLD' ,
122
- 'default_value' : 500
123
- },
124
- {
125
- 'flask_oauthlib_key' : 'OAUTH2_CACHE_KEY_PREFIX' ,
126
- 'flask_cache_key' : 'CACHE_KEY_PREFIX' ,
127
- 'default_value' : None
128
- },
129
- {
130
- 'flask_oauthlib_key' : 'OAUTH2_CACHE_MEMCACHED_SERVERS' ,
131
- 'flask_cache_key' : 'CACHE_MEMCACHED_SERVERS' ,
132
- 'default_value' : None
133
- },
134
- {
135
- 'flask_oauthlib_key' : 'OAUTH2_CACHE_REDIS_HOST' ,
136
- 'flask_cache_key' : 'CACHE_REDIS_HOST' ,
137
- 'default_value' : 'localhost'
138
- },
139
- {
140
- 'flask_oauthlib_key' : 'OAUTH2_CACHE_REDIS_PORT' ,
141
- 'flask_cache_key' : 'CACHE_REDIS_PORT' ,
142
- 'default_value' : 6379
143
- },
144
- {
145
- 'flask_oauthlib_key' : 'OAUTH2_CACHE_REDIS_PASSWORD' ,
146
- 'flask_cache_key' : 'CACHE_REDIS_PASSWORD' ,
147
- 'default_value' : None
148
- },
149
- {
150
- 'flask_oauthlib_key' : 'OAUTH2_CACHE_REDIS_DB' ,
151
- 'flask_cache_key' : 'CACHE_REDIS_DB' ,
152
- 'default_value' : 0
153
- },
154
- {
155
- 'flask_oauthlib_key' : 'OAUTH2_CACHE_DIR' ,
156
- 'flask_cache_key' : 'CACHE_DIR' ,
157
- 'default_value' : None
158
- },
159
- {
160
- 'flask_oauthlib_key' : 'OAUTH2_CACHE_MODE' ,
161
- 'flask_cache_key' : 'CACHE_MODE' ,
162
- 'default_value' : '0600'
163
- },
164
- {
165
- 'flask_oauthlib_key' : 'OAUTH2_CACHE_TYPE' ,
166
- 'flask_cache_key' : 'CACHE_TYPE' ,
167
- 'default_value' : 'null'
168
- },
169
- )
170
-
171
- for setting in settings :
172
- flask_oauthlib_key = setting ['flask_oauthlib_key' ]
173
- flask_cache_key = setting ['flask_cache_key' ]
174
- if flask_cache_key in config and flask_oauthlib_key not in config :
175
- config [flask_oauthlib_key ] = config [flask_cache_key ]
176
- else :
177
- config .setdefault (flask_oauthlib_key , setting ['default_value' ])
178
-
179
- self .config = config
180
- kwargs = dict (default_timeout = config ['OAUTH2_CACHE_DEFAULT_TIMEOUT' ])
181
- cache_type = '_{0}' .format (config ['OAUTH2_CACHE_TYPE' ])
182
-
183
- try :
184
- self .cache = getattr (self , cache_type )(kwargs )
185
- except AttributeError :
186
- raise AttributeError (
187
- '`{0}` is not a valid cache type!' .format (cache_type ))
188
-
189
- provider .grantgetter (self .get )
190
- provider .grantsetter (self .set )
191
-
192
- def _null (self , kwargs ):
193
- """Returns a :class:`NullCache` instance"""
194
- return NullCache ()
195
-
196
- def _simple (self , kwargs ):
197
- """Returns a :class:`SimpleCache` instance
198
-
199
- .. warning::
200
-
201
- This cache system might not be thread safe. Use with caution.
202
-
203
- """
204
- kwargs .update (dict (threshold = self .config ['OAUTH2_CACHE_THRESHOLD' ]))
205
- return SimpleCache (** kwargs )
206
-
207
- def _memcache (self , kwargs ):
208
- """Returns a :class:`MemcachedCache` instance"""
209
- kwargs .update (dict (
210
- servers = self .config ['OAUTH2_CACHE_MEMCACHED_SERVERS' ],
211
- key_prefix = self .config ['OAUTH2_CACHE_KEY_PREFIX' ]
212
- ))
213
- return MemcachedCache (** kwargs )
214
-
215
- def _redis (self , kwargs ):
216
- """Returns a :class:`RedisCache` instance"""
217
- kwargs .update (dict (
218
- host = self .config ['OAUTH2_CACHE_REDIS_HOST' ],
219
- port = self .config ['OAUTH2_CACHE_REDIS_PORT' ],
220
- password = self .config ['OAUTH2_CACHE_REDIS_PASSWORD' ],
221
- db = self .config ['OAUTH2_CACHE_REDIS_DB' ],
222
- key_prefix = self .config ['OAUTH2_CACHE_KEY_PREFIX' ]
223
- ))
224
- return RedisCache (** kwargs )
225
-
226
- def _filesystem (self , kwargs ):
227
- """Returns a :class:`FileSystemCache` instance"""
228
- kwargs .update (dict (
229
- threshold = self .config ['OAUTH2_CACHE_THRESHOLD' ]
230
- ))
231
- return FileSystemCache (self .config ['OAUTH2_CACHE_DIR' ], ** kwargs )
232
-
233
- def set (self , client_id , code , request , * args , ** kwargs ):
69
+ @provider .grantsetter
70
+ def create_grant (client_id , code , request , * args , ** kwargs ):
234
71
"""Sets the grant token with the configured cache system"""
235
72
grant = Grant (
236
- self . cache ,
237
- client_id = request . client . client_id ,
73
+ cache ,
74
+ client_id = client_id ,
238
75
code = code ['code' ],
239
76
redirect_uri = request .redirect_uri ,
240
77
scopes = request .scopes ,
241
- user = self . current_user ()
78
+ user = current_user ()
242
79
)
243
80
log .debug ("Set Grant Token with key {0}" .format (grant .key ))
244
- self . cache .set (grant .key , dict (grant ))
81
+ cache .set (grant .key , dict (grant ))
245
82
246
- def get (self , client_id , code ):
83
+ @provider .grantgetter
84
+ def get (client_id , code ):
247
85
"""Gets the grant token with the configured cache system"""
248
- grant = Grant (self . cache , client_id = client_id , code = code )
249
- kwargs = self . cache .get (grant .key )
250
- if kwargs :
251
- log .debug ("Grant Token found with key {0}" . format ( grant .key ) )
252
- for k , v in kwargs . items ():
253
- setattr ( grant , k , v )
254
- return grant
255
- log . debug ( "Grant Token not found with key {0}" . format (grant . key ) )
256
- return None
86
+ grant = Grant (cache , client_id = client_id , code = code )
87
+ ret = cache .get (grant .key )
88
+ if not ret :
89
+ log .debug ("Grant Token not found with key %s" % grant .key )
90
+ return None
91
+ log . debug ( "Grant Token found with key %s" % grant . key )
92
+ for k , v in ret . items ():
93
+ setattr (grant , k , v )
94
+ return grant
257
95
258
96
259
97
class SQLAlchemyBinding (object ):
0 commit comments