OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/env python |
| 2 # |
| 3 # Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 4 # Use of this source code is governed by a BSD-style license that can be |
| 5 # found in the LICENSE file. |
| 6 |
| 7 # Chromoting Directory API client implementation. Used for testing/debugging |
| 8 # purposes. Requires Python 2.6: json module is not available in earlier |
| 9 # versions. |
| 10 |
| 11 import os |
| 12 import httplib |
| 13 import json |
| 14 import urllib |
| 15 import urllib2 |
| 16 import random |
| 17 import sys |
| 18 |
| 19 DEFAULT_DIRECTORY_SERVER = 'www-googleapis-test.sandbox.google.com' |
| 20 |
| 21 auth_filepath = os.path.join(os.path.expanduser('~'), |
| 22 '.chromotingDirectoryAuthToken') |
| 23 |
| 24 def random_uuid(): |
| 25 return ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x" % |
| 26 tuple(map(lambda x: random.randrange(0,65536), range(8)))) |
| 27 |
| 28 class Host: |
| 29 def __init__(self, parameters=None): |
| 30 if parameters != None: |
| 31 self.host_id = parameters[u"hostId"] |
| 32 self.host_name = parameters[u"hostName"] |
| 33 self.public_key = parameters[u"publicKey"] |
| 34 # Following fields may be missing, use get() for them. |
| 35 self.jabber_id = parameters.get(u"jabberId") |
| 36 self.created_time = parameters.get(u"createdTime") |
| 37 self.updated_time = parameters.get(u"updatedTime") |
| 38 self.status = parameters.get(u"status") |
| 39 else: |
| 40 self.host_id = random_uuid() |
| 41 import socket |
| 42 self.host_name = socket.gethostname() |
| 43 self.public_key = None |
| 44 self.jabber_id = None |
| 45 self.created_time = None |
| 46 self.updated_time = None |
| 47 self.status = None |
| 48 |
| 49 class HostDirectoryError(Exception): |
| 50 def __init__(self, message, response): |
| 51 Exception.__init__(self, message) |
| 52 print response |
| 53 self._response = response |
| 54 |
| 55 class HostDirectory: |
| 56 def __init__(self, username, auth_token, server=DEFAULT_DIRECTORY_SERVER): |
| 57 self._username = username |
| 58 self._auth_token = auth_token |
| 59 self._base_url = '/chromoting/v1/@me/hosts' |
| 60 |
| 61 self._http = httplib.HTTPConnection(server) |
| 62 self._headers = {"Authorization": "GoogleLogin auth=" + self._auth_token, |
| 63 "Content-Type": "application/json" } |
| 64 |
| 65 def add_host(self, host): |
| 66 host_json = { 'data': |
| 67 { 'hostId': host.host_id, |
| 68 'hostName': host.host_name, |
| 69 'publicKey': host.public_key, |
| 70 } |
| 71 } |
| 72 if host.jabber_id: |
| 73 host_json['data']['jabberId'] = host.jabber_id |
| 74 post_data = json.dumps(host_json) |
| 75 self._http.request("POST", self._base_url, post_data, self._headers) |
| 76 response = self._http.getresponse() |
| 77 if response.status != 200: |
| 78 raise HostDirectoryError(response.reason, response.read()) |
| 79 data = response.read() |
| 80 |
| 81 def get_hosts(self): |
| 82 self._http.request("GET", self._base_url, headers=self._headers) |
| 83 response = self._http.getresponse() |
| 84 if response.status != 200: |
| 85 raise HostDirectoryError(response.reason, response.read()) |
| 86 data = response.read() |
| 87 data = json.loads(data)[u'data'] |
| 88 results = [] |
| 89 if data.has_key(u'items'): |
| 90 for item in data[u'items']: |
| 91 results.append(Host(item)) |
| 92 return results |
| 93 |
| 94 def delete_host(self, host_id): |
| 95 url = self._base_url + '/' + host_id |
| 96 self._http.request("DELETE", url, headers=self._headers) |
| 97 response = self._http.getresponse() |
| 98 if response.status / 100 != 2: # Normally 204 is returned |
| 99 raise HostDirectoryError(response.reason, response.read()) |
| 100 data = response.read() |
| 101 |
| 102 def usage(): |
| 103 sys.stderr.write( |
| 104 ("Usage:\n" + |
| 105 " Login: \t\t%(cmd)s login\n" + |
| 106 " Register host: \t%(cmd)s insert --hostId=<hostId>" + |
| 107 " --hostName=<hostName> \\\n" + |
| 108 "\t\t\t --publicKey=<publicKey> --jabberId=<jabberId>\n" + |
| 109 " List hosts: \t\t%(cmd)s list\n" + |
| 110 " Delete a host: \t%(cmd)s delete <host_id>\n") |
| 111 % {"cmd" : sys.argv[0]}) |
| 112 return 1 |
| 113 |
| 114 class CommandError(Exception): |
| 115 def __init__(self, message): |
| 116 Exception.__init__(self, message) |
| 117 |
| 118 def load_auth_token(): |
| 119 try: |
| 120 lines = open(auth_filepath).readlines() |
| 121 except IOError as e: |
| 122 raise CommandError("Can't open file (%s). Please run " + |
| 123 "'%s login' and try again." % |
| 124 (auth_filepath, sys.argv[0])) |
| 125 if len(lines) != 2: |
| 126 raise CommandError("Invalid auth file (%s). Please run " + |
| 127 "'%s login' and try again." % |
| 128 (auth_filepath, sys.argv[0])) |
| 129 return map(lambda x: x.strip(), lines) |
| 130 |
| 131 def login_cmd(args): |
| 132 """login command""" |
| 133 if len(args) != 0: |
| 134 return usage() |
| 135 |
| 136 import getpass |
| 137 import gaia_auth |
| 138 |
| 139 print "Email:", |
| 140 email = raw_input() |
| 141 passwd = getpass.getpass("Password: ") |
| 142 |
| 143 authenticator = gaia_auth.GaiaAuthenticator('chromoting'); |
| 144 auth_token = authenticator.authenticate(email, passwd) |
| 145 |
| 146 # Set permission mask for created file. |
| 147 os.umask(0066) |
| 148 auth_file = open(auth_filepath, 'w') |
| 149 auth_file.write(email) |
| 150 auth_file.write('\n') |
| 151 auth_file.write(auth_token) |
| 152 auth_file.close() |
| 153 |
| 154 print 'Auth token: ', auth_token |
| 155 print '...saved in', auth_filepath |
| 156 |
| 157 def list_cmd(args): |
| 158 """list command""" |
| 159 if len(args) != 0: |
| 160 return usage() |
| 161 (username, token) = load_auth_token() |
| 162 client = HostDirectory(username, token) |
| 163 print '%36s %30s %s' % ("HOST ID", "HOST NAME", "JABBER ID") |
| 164 for host in client.get_hosts(): |
| 165 print '%36s %30s %s' % (host.host_id, host.host_name, host.jabber_id) |
| 166 return 0 |
| 167 |
| 168 def insert_cmd(args): |
| 169 """insert command""" |
| 170 (username, token) = load_auth_token() |
| 171 client = HostDirectory(username, token) |
| 172 |
| 173 host = Host() |
| 174 for arg in args: |
| 175 if arg.startswith("--hostId="): |
| 176 host.host_id = arg[len("--hostId="):] |
| 177 elif arg.startswith("--hostName="): |
| 178 host.host_name = arg[len("--hostName="):] |
| 179 elif arg.startswith("--publicKey="): |
| 180 host.public_key = arg[len("--publicKey="):] |
| 181 elif arg.startswith("--jabberId="): |
| 182 host.jabber_id = arg[len("--jabberId="):] |
| 183 else: |
| 184 return usage() |
| 185 |
| 186 client.add_host(host) |
| 187 return 0 |
| 188 |
| 189 def delete_cmd(args): |
| 190 """delete command""" |
| 191 if len(args) != 1: |
| 192 return usage() |
| 193 host_id = args[0] |
| 194 (username, token) = load_auth_token() |
| 195 client = HostDirectory(username, token) |
| 196 client.delete_host(host_id) |
| 197 return 0 |
| 198 |
| 199 def main(): |
| 200 import sys |
| 201 args = sys.argv[1:] |
| 202 if len(args) == 0: |
| 203 return usage() |
| 204 command = args[0] |
| 205 |
| 206 try: |
| 207 if command == "help": |
| 208 usage() |
| 209 elif command == "login": |
| 210 return login_cmd(args[1:]) |
| 211 elif command == "list": |
| 212 return list_cmd(args[1:]) |
| 213 elif command == "insert": |
| 214 return insert_cmd(args[1:]) |
| 215 elif command == "delete": |
| 216 return delete_cmd(args[1:]) |
| 217 else: |
| 218 raise CommandError("Unknown command: %s" % command); |
| 219 |
| 220 except CommandError as e: |
| 221 sys.stderr.write("%s\n" % e.args[0]) |
| 222 return 1 |
| 223 |
| 224 return 0 |
| 225 |
| 226 if __name__ == '__main__': |
| 227 sys.exit(main()) |
OLD | NEW |