Home | History | Annotate | Download | only in fake_device_server
      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