aboutsummaryrefslogtreecommitdiff
path: root/client/common_lib/cros/fake_device_server/common_util.py
blob: d89fa864a787b05ac5877bddb9b2efa76d8ca0ea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# Copyright 2014 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Common Utility Methods"""

import cherrypy
import json
import logging

import common
from fake_device_server import server_errors


def parse_serialized_json():
    """Parses incoming cherrypy request as a json."""
    body_length = int(cherrypy.request.headers.get('Content-Length', 0))
    data = cherrypy.request.rfile.read(body_length)
    return json.loads(data) if data else None


def grab_header_field(header_name):
    """Returns the header |header_name| from an incoming request.

    @param header_name: Header name to retrieve.
    """
    return cherrypy.request.headers.get(header_name, None)


def get_access_token():
    """Returns the access token from an incoming request.

    @return string access token or None.

    """
    header = grab_header_field('Authorization')
    if header is None:
        logging.error('No authorization header found.')
        return None
    fields = header.split()
    if len(fields) != 2 or fields[0] != "Bearer":
        logging.error('No access token found.')
        return None
    logging.debug('Got authorization header "%s"', header)
    return fields[1]


def parse_common_args(args_tuple, kwargs, supported_operations=set()):
    """Common method to parse args to a CherryPy RPC for this server.

    |args_tuple| should contain all the sections of the URL after CherryPy
    removes the pieces that dispatched the URL to this handler. For instance,
    a GET method receiving '...'/<id>/<method_name> should call:
    parse_common_args(args_tuple=[<id>, <method_name>]).
    Some operations take no arguments. Other operations take
    a single argument. Still other operations take
    one of supported_operations as a second argument (in the args_tuple).

    @param args_tuple: Tuple of positional args.
    @param kwargs: Dictionary of named args passed in.
    @param supported_operations: Set of operations to support if any.

    Returns:
        A 3-tuple containing the id parsed from the args_tuple, api_key,
        and finally an optional operation if supported_operations is provided
        and args_tuple contains one of the supported ops.

    Raises:
        server_error.HTTPError if combination or args/kwargs doesn't make
        sense.
    """
    args = list(args_tuple)
    api_key = kwargs.get('key')
    id = args.pop(0) if args else None
    operation = args.pop(0) if args else None
    if operation:
        if not supported_operations:
            raise server_errors.HTTPError(
                    400, 'Received operation when operation was not '
                    'expected: %s!' % operation)
        elif not operation in supported_operations:
            raise server_errors.HTTPError(
                    400, 'Unsupported operation: %s' % operation)

    # All expected args should be popped off already.
    if args:
        raise server_errors.HTTPError(
                400, 'Could not parse all args: %s' % args)

    return id, api_key, operation