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"""Module contains a simple client lib to the registration RPC."""
6
7import json
8import logging
9import urllib2
10
11import common
12from fake_device_server.client_lib import common_client
13from fake_device_server import registration_tickets
14
15
16class RegistrationClient(common_client.CommonClient):
17    """Client library for registrationTickets method."""
18
19    def __init__(self, *args, **kwargs):
20        common_client.CommonClient.__init__(
21                self, registration_tickets.REGISTRATION_PATH, *args, **kwargs)
22
23
24    def get_registration_ticket(self, ticket_id):
25        """Returns info about the given |ticket_id|.
26
27        @param ticket_id: valid id for a ticket.
28        """
29        url_h = urllib2.urlopen(self.get_url([ticket_id]))
30        return json.loads(url_h.read())
31
32
33    def update_registration_ticket(self, ticket_id, data,
34                                   additional_headers=None, replace=False):
35        """Updates the given registration ticket with the new data.
36
37        @param ticket_id: id of the ticket to update.
38        @param data: data to update.
39        @param additional_headers: additional HTTP headers to pass (expects a
40                list of tuples).
41        @param replace: If True, replace all data with the given data using the
42                PUT operation.
43        """
44        if not data:
45            return
46
47        headers = {'Content-Type': 'application/json'}
48        if additional_headers:
49            headers.update(additional_headers)
50
51        request = urllib2.Request(self.get_url([ticket_id]), json.dumps(data),
52                                  headers=headers)
53        if replace:
54            request.get_method = lambda: 'PUT'
55        else:
56            request.get_method = lambda: 'PATCH'
57
58        url_h = urllib2.urlopen(request)
59        return json.loads(url_h.read())
60
61
62    def create_registration_ticket(self):
63        """Creates a new registration ticket."""
64        # We're going to fall back onto this test access token, if we don't
65        # have a real one.  Tests rely on this behavior.
66        token = registration_tickets.RegistrationTickets.TEST_ACCESS_TOKEN
67        headers = {'Content-Type': 'application/json',
68                   'Authorization': 'Bearer %s' % token,
69        }
70        auth_headers = self.add_auth_headers()
71        headers.update(auth_headers)
72        data = {'userEmail': 'me'}
73        request = urllib2.Request(self.get_url(), json.dumps(data), headers)
74        url_h = urllib2.urlopen(request)
75        return json.loads(url_h.read())
76
77
78    def finalize_registration_ticket(self, ticket_id):
79        """Finalizes a registration ticket by creating a new device.
80
81        @param ticket_id: id of ticket to finalize.
82        """
83        request = urllib2.Request(self.get_url([ticket_id, 'finalize']),
84                                  data='')
85        url_h = urllib2.urlopen(request)
86        return json.loads(url_h.read())
87
88
89    def register_device(self, system_name, channel,
90                        oauth_client_id, **kwargs):
91        """Goes through the entire registration process using the device args.
92
93        @param system_name: name to give the system.
94        @param channel: supported communication channel.
95        @param oauth_client_id: see oauth docs.
96        @param kwargs: additional dictionary of args to put in config.
97        """
98        ticket = self.create_registration_ticket()
99        logging.info('Initial Ticket: %s', ticket)
100        ticket_id = ticket['id']
101
102        device_draft = dict(name=system_name,
103                            channel=dict(supportedType=channel),
104                            **kwargs)
105
106        ticket = self.update_registration_ticket(
107                ticket_id,
108                {'deviceDraft': device_draft,
109                 'userEmail': 'me',
110                 'oauthClientId': oauth_client_id})
111
112        logging.info('Updated Ticket After Claiming: %s', ticket)
113        return self.finalize_registration_ticket(ticket_id)
114