1 # Copyright 2014 The Chromium OS Authors. All rights reserved. 2 # Use of this source code is governed by a BSD-style license that can be 3 # found in the LICENSE file. 4 5 """Common Utility Methods""" 6 7 import cherrypy 8 import json 9 import logging 10 11 import common 12 from fake_device_server import server_errors 13 14 15 def parse_serialized_json(): 16 """Parses incoming cherrypy request as a json.""" 17 body_length = int(cherrypy.request.headers.get('Content-Length', 0)) 18 data = cherrypy.request.rfile.read(body_length) 19 return json.loads(data) if data else None 20 21 22 def grab_header_field(header_name): 23 """Returns the header |header_name| from an incoming request. 24 25 @param header_name: Header name to retrieve. 26 """ 27 return cherrypy.request.headers.get(header_name, None) 28 29 30 def get_access_token(): 31 """Returns the access token from an incoming request. 32 33 @return string access token or None. 34 35 """ 36 header = grab_header_field('Authorization') 37 if header is None: 38 logging.error('No authorization header found.') 39 return None 40 fields = header.split() 41 if len(fields) != 2 or fields[0] != "Bearer": 42 logging.error('No access token found.') 43 return None 44 logging.debug('Got authorization header "%s"', header) 45 return fields[1] 46 47 48 def parse_common_args(args_tuple, kwargs, supported_operations=set()): 49 """Common method to parse args to a CherryPy RPC for this server. 50 51 |args_tuple| should contain all the sections of the URL after CherryPy 52 removes the pieces that dispatched the URL to this handler. For instance, 53 a GET method receiving '...'/<id>/<method_name> should call: 54 parse_common_args(args_tuple=[<id>, <method_name>]). 55 Some operations take no arguments. Other operations take 56 a single argument. Still other operations take 57 one of supported_operations as a second argument (in the args_tuple). 58 59 @param args_tuple: Tuple of positional args. 60 @param kwargs: Dictionary of named args passed in. 61 @param supported_operations: Set of operations to support if any. 62 63 Returns: 64 A 3-tuple containing the id parsed from the args_tuple, api_key, 65 and finally an optional operation if supported_operations is provided 66 and args_tuple contains one of the supported ops. 67 68 Raises: 69 server_error.HTTPError if combination or args/kwargs doesn't make 70 sense. 71 """ 72 args = list(args_tuple) 73 api_key = kwargs.get('key') 74 id = args.pop(0) if args else None 75 operation = args.pop(0) if args else None 76 if operation: 77 if not supported_operations: 78 raise server_errors.HTTPError( 79 400, 'Received operation when operation was not ' 80 'expected: %s!' % operation) 81 elif not operation in supported_operations: 82 raise server_errors.HTTPError( 83 400, 'Unsupported operation: %s' % operation) 84 85 # All expected args should be popped off already. 86 if args: 87 raise server_errors.HTTPError( 88 400, 'Could not parse all args: %s' % args) 89 90 return id, api_key, operation 91