Package restkit :: Package oauth2 :: Module filter
[hide private]
[frames] | no frames]

Source Code for Module restkit.oauth2.filter

  1  # -*- coding: utf-8 - 
  2  # 
  3  # This file is part of restkit released under the MIT license.  
  4  # See the NOTICE for more information. 
  5   
  6  import re 
  7  import urlparse 
  8  try: 
  9      from urlparse import parse_qsl 
 10  except ImportError: 
 11      from cgi import parse_qsl 
 12       
 13  from restkit.oauth2 import Consumer, Request, SignatureMethod_HMAC_SHA1,\ 
 14  Token 
 15   
 16       
 17  from restkit import util 
 18   
19 -def validate_consumer(consumer):
20 """ validate a consumer agains oauth2.Consumer object """ 21 if not isinstance(consumer, Consumer): 22 raise ValueError("Invalid consumer.") 23 return consumer
24
25 -def validate_token(token):
26 """ validate a token agains oauth2.Token object """ 27 if token is not None and not isinstance(token, Token): 28 raise ValueError("Invalid token.") 29 return token
30 31
32 -class OAuthFilter(object):
33
34 - def __init__(self, rules):
35 """ 36 Initalize Oauth filter wiht a tupple or list of tupples:: 37 38 (path, consumer, token, signaturemethod) 39 40 token and method signature are optionnals. Consumer should be an 41 instance of `oauth2.Consumer`, token an instance of `oauth2.Toke` 42 signature method an instance of `oauth2.SignatureMethod`. 43 44 With a list of tupple, the filter will try to match the path with 45 the rule. It allows you to maintain different authorization per 46 path. A wildcard at the indicate to the filter to match all path 47 behind. 48 49 Example the rule:: 50 51 /some/resource/* 52 53 will match : 54 55 /some/resource/other 56 /some/resource/other2 57 58 while the rule `/some/resource` will only match the path 59 `/some/resource`. 60 61 62 """ 63 64 if not isinstance(rules, list): 65 self.rules = [rules] 66 else: 67 self.rules = rules 68 self.resources = {} 69 self.matches = [] 70 self.parse_rules()
71
72 - def parse_rules(self):
73 for rule in self.rules: 74 self.add_rule(rule)
75
76 - def add_rule(self, rule):
77 default_method = SignatureMethod_HMAC_SHA1() 78 if len(rule) == 2: 79 # path, consumer 80 r = (validate_consumer(rule[1]), None, default_method) 81 elif len(rule) == 3: 82 r = (validate_consumer(rule[1]), validate_token(rule[2]), 83 default_method) 84 elif len(rule) == 4: 85 r = (validate_consumer(rule[1]), validate_token(rule[2]), 86 rule[3] or default_method) 87 else: 88 raise ValueError("Invalid OAUTH resource.") 89 90 path = rule[0] 91 if path.endswith('*'): 92 re_path = re.compile("%s.*" % path.rsplit('*', 1)[0]) 93 else: 94 re_path = re.compile("%s$" % path) 95 self.matches.append(re_path) 96 self.resources[re_path] = r
97
98 - def on_path(self, req):
99 path = req.uri.path or "/" 100 for m in self.matches: 101 if m.match(path) is not None: 102 return self.resources[m] 103 return False
104
105 - def on_request(self, req):
106 resource = self.on_path(req) 107 if not resource: 108 return 109 consumer, token, method = resource 110 111 headers = dict(req.headers) 112 params = {} 113 form = False 114 if req.body and req.body is not None: 115 ctype = headers.get('Content-Type') 116 if ctype is not None and \ 117 ctype.startswith('application/x-www-form-urlencoded'): 118 # we are in a form try to get oauth params from here 119 form = True 120 params = dict(parse_qsl(req.body)) 121 122 # update params from quey parameters 123 params.update(parse_qsl(req.uri.query)) 124 125 oauth_req = Request.from_consumer_and_token(consumer, token=token, 126 http_method=req.method, http_url=req.url, 127 parameters=params) 128 129 oauth_req.sign_request(method, consumer, token) 130 131 if form: 132 req.body = oauth_req.to_postdata() 133 elif req.method in ('GET', 'HEAD'): 134 req.url = req.final_url = oauth_req.to_url() 135 req.uri = urlparse.urlparse(req.url) 136 else: 137 oauth_headers = oauth_req.to_header() 138 for k, v in list(oauth_headers.items()): 139 k = util.normalize_name(k) 140 if not isinstance(v, basestring): 141 v = str(v) 142 req.headers.append((k, v))
143