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