Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / remoting / webapp / crd / js / gcd_client.js
blob5bfab9fdef3ecc98a1fd2d9072bd05cd85a925d4
1 // Copyright 2015 The Chromium 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.
5 /**
6  * @fileoverview
7  * Client for the GCD REST API.
8  * TODO: Add link to GCD docs.
9  */
11 /** @suppress {duplicate} */
12 var remoting = remoting || {};
14 /**
15  * Namespace for GCD definitions
16  * @type {Object}
17  */
18 remoting.gcd = remoting.gcd || {};
20 /**
21  * @typedef {{
22  *   id: string,
23  *   robotAccountEmail: string,
24  *   robotAccountAuthorizationCode: string,
25  *   deviceId: string,
26  *   deviceDraft: Object
27  * }}
28  */
29 remoting.gcd.RegistrationTicket;
31 /**
32  * TODO: Flesh out with typical fields.
33  * @typedef {{
34  *   id:string,
35  *   name:string,
36  *   state:(!Object|undefined),
37  *   tags:(!Array<string>|undefined)
38  * }}
39  */
40 remoting.gcd.Device;
42 /**
43  * @typedef {!Object}
44  */
45 remoting.gcd.DevicePatch;
47 /**
48  * @typedef {{
49  *   devices: (Array<remoting.gcd.Device>|undefined)
50  * }}
51  */
52 remoting.gcd.DeviceListResponse;
54 (function() {
55 'use strict';
57 /**
58  * Interprets an HTTP response as a JSON object with a specific value
59  * in the 'kind' field.
60  * @param {remoting.Xhr.Response} response
61  * @param {string} expectedKind
62  * @return {!Object}
63  * @throws {remoting.Error}
64  */
65 var responseAsObject = function(response, expectedKind) {
66   if (typeof response.getJson() != 'object') {
67     console.error(
68         'invalid response; expected object, got:', response.getJson());
69     throw remoting.Error.unexpected();
70   }
71   var obj = base.assertObject(response.getJson());
72   var kind = base.getStringAttr(obj, 'kind');
73   if (kind != expectedKind) {
74     console.error(
75         'invalid resonse kind; expected ' + expectedKind + ', got ' + kind);
76     throw remoting.Error.unexpected();
77   }
78   return obj;
81 /**
82  * Interprets an HTTP response as containing a GCD registration ticket.
83  * @param {remoting.Xhr.Response} response
84  * @return {!remoting.gcd.RegistrationTicket}
85  * @throws {remoting.Error}
86  */
87 var responseAsGcdRegistrationTicket = function(response) {
88   return /** @type {!remoting.gcd.RegistrationTicket} */ (
89       responseAsObject(
90           response, 'clouddevices#registrationTicket'));
93 /**
94  * Interprets an HTTP response as containing a GCD device defintion.
95  * @param {remoting.Xhr.Response} response
96  * @return {!remoting.gcd.Device}
97  * @throws {remoting.Error}
98  */
99 var responseAsGcdDevice = function(response) {
100   return /** @type {!remoting.gcd.Device} */ (
101       responseAsObject(response, 'clouddevices#device'));
105  * Interprets an HTTP response as containing a GCD device list.
106  * @param {remoting.Xhr.Response} response
107  * @return {!remoting.gcd.DeviceListResponse}
108  * @throws {remoting.Error}
109  */
110 var responseAsGcdDeviceListResponse = function(response) {
111   return /** @type {!remoting.gcd.DeviceListResponse} */ (
112       responseAsObject(response, 'clouddevices#devicesListResponse'));
116  * Creates a new client using a specific API key, and optionall a
117  * specific base URL, and OAuth2 client ID.
118  * @param {{
119  *   apiKey: string,
120  *   apiBaseUrl: (string|undefined)
121  * }} options
122  * @constructor
123  */
124 remoting.gcd.Client = function(options) {
125   /** @const */
126   this.apiKey_ = options.apiKey;
127   /** @const */
128   this.apiBaseUrl_ = options.apiBaseUrl ||
129       'https://www.googleapis.com/clouddevices/v1';
133  * Creates a new registration ticket.
134  * TODO: Add link to GCD docs.
135  * @return {!Promise<remoting.gcd.RegistrationTicket>}
136  */
137 remoting.gcd.Client.prototype.insertRegistrationTicket = function() {
138   return new remoting.Xhr({
139     method: 'POST',
140     url: this.apiBaseUrl_ + '/registrationTickets',
141     jsonContent: { 'userEmail': 'me' },
142     useIdentity: true,
143     acceptJson: true
144   }).start().then(function(/** remoting.Xhr.Response */ response) {
145     if (response.isError()) {
146       console.error('error creating registration ticket');
147       throw remoting.Error.unexpected();
148     }
149     return responseAsGcdRegistrationTicket(response);
150   });
154  * Updates an existing registration ticket using patch semantics.
155  * TODO: Add link to GCD docs.
156  * @param {string} ticketId
157  * @param {!Object<*>} deviceDraft
158  * @param {string} oauthClientId
159  * @return {!Promise<remoting.gcd.RegistrationTicket>}
160  */
161 remoting.gcd.Client.prototype.patchRegistrationTicket = function(
162     ticketId, deviceDraft, oauthClientId) {
163   return new remoting.Xhr({
164     method: 'PATCH',
165     url: this.apiBaseUrl_ + '/registrationTickets/' +
166         encodeURIComponent(ticketId),
167     urlParams: {
168       'key': this.apiKey_
169     },
170     jsonContent: {
171       'deviceDraft': deviceDraft,
172       'oauthClientId': oauthClientId
173     },
174     acceptJson: true
175   }).start().then(function(response) {
176     if (response.isError()) {
177       console.error('error patching registration ticket');
178       throw remoting.Error.unexpected();
179     }
180     return responseAsGcdRegistrationTicket(response);
181   });
185  * Finalizes device registration and returns its credentials.
186  * TODO: Add link to GCD docs.
187  * @param {string} ticketId
188  * @return {!Promise<remoting.gcd.RegistrationTicket>}
189  */
190 remoting.gcd.Client.prototype.finalizeRegistrationTicket = function(ticketId) {
191   return new remoting.Xhr({
192     method: 'POST',
193     url: this.apiBaseUrl_ + '/registrationTickets/' +
194         encodeURIComponent(ticketId) + '/finalize',
195     urlParams: {
196       'key': this.apiKey_
197     },
198     acceptJson: true
199   }).start().then(function(response) {
200     if (response.isError()) {
201       console.error('error finalizing registration ticket');
202       throw remoting.Error.unexpected();
203     }
204     return responseAsGcdRegistrationTicket(response);
205   });
209  * Lists devices user has access to.
210  * TODO: Add link to GCD docs.
211  * @return {!Promise<!Array<remoting.gcd.Device>>}
212  */
213 remoting.gcd.Client.prototype.listDevices = function() {
214   return new remoting.Xhr({
215     method: 'GET',
216     url: this.apiBaseUrl_ + '/devices',
217     useIdentity: true,
218     acceptJson: true
219   }).start().then(function(response) {
220     if (response.isError()) {
221       console.error('error getting device list');
222       throw remoting.Error.unexpected();
223     }
224     var hosts = responseAsGcdDeviceListResponse(response);
225     return hosts.devices || [];
226   });
230  * Deletes a device from the system.
231  * TODO: Add link to GCD docs.
232  * @param {string} deviceId
233  * @return {!Promise<boolean>} Promise that resolves to true if the
234  *     device was deleted, false if there was no such device ID.
235  */
236 remoting.gcd.Client.prototype.deleteDevice = function(deviceId) {
237   return new remoting.Xhr({
238     method: 'DELETE',
239     url: this.apiBaseUrl_ + '/devices/' + deviceId,
240     useIdentity: true
241   }).start().then(function(response) {
242     if (response.status == 404) {
243       return false;
244     }
245     if (response.isError()) {
246       console.error('error deleting device');
247       throw remoting.Error.unexpected();
248     }
249     return true;
250   });
254  * Updates a device data using patch semantics.
255  * TODO: Add link to GCD docs.
256  * @param {string} deviceId
257  * @param {!Object<*>} patch
258  * @return {!Promise<remoting.gcd.Device>}
259  */
260 remoting.gcd.Client.prototype.patchDevice = function(deviceId, patch) {
261   return new remoting.Xhr({
262     method: 'PATCH',
263     url: this.apiBaseUrl_ + '/devices/' + deviceId,
264     jsonContent: patch,
265     useIdentity: true,
266     acceptJson: true
267   }).start().then(function(response) {
268     if (response.isError()) {
269       console.error('error patching device');
270       throw remoting.Error.unexpected();
271     }
272     return responseAsGcdDevice(response);
273   });
276 })();