blob: c9e01a10c38627081fcae7257544709b7c78c465 [file] [log] [blame]
#!/usr/bin/env python
#
# Copyright (c) 2010 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# Chromoting Directory API client implementation. Used for testing/debugging
# purposes. Requires Python 2.6: json module is not available in earlier
# versions.
import os
import httplib
import json
import urllib
import urllib2
import random
import sys
DEFAULT_DIRECTORY_SERVER = 'www.googleapis.com'
auth_filepath = os.path.join(os.path.expanduser('~'),
'.chromotingDirectoryAuthToken')
def random_uuid():
return ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x" %
tuple(map(lambda x: random.randrange(0,65536), range(8))))
class Host:
def __init__(self, parameters=None):
if parameters != None:
self.host_id = parameters[u"hostId"]
self.host_name = parameters[u"hostName"]
self.public_key = parameters[u"publicKey"]
# Following fields may be missing, use get() for them.
self.jabber_id = parameters.get(u"jabberId")
self.created_time = parameters.get(u"createdTime")
self.updated_time = parameters.get(u"updatedTime")
self.status = parameters.get(u"status")
else:
self.host_id = random_uuid()
import socket
self.host_name = socket.gethostname()
self.public_key = None
self.jabber_id = None
self.created_time = None
self.updated_time = None
self.status = None
class HostDirectoryError(Exception):
def __init__(self, message, response):
Exception.__init__(self, message)
print response
self._response = response
class HostDirectory:
def __init__(self, username, auth_token, server=DEFAULT_DIRECTORY_SERVER):
self._username = username
self._auth_token = auth_token
self._base_url = '/chromoting/v1/@me/hosts'
self._http = httplib.HTTPSConnection(server)
self._headers = {"Authorization": "GoogleLogin auth=" + self._auth_token,
"Content-Type": "application/json" }
def add_host(self, host):
host_json = { 'data':
{ 'hostId': host.host_id,
'hostName': host.host_name,
'publicKey': host.public_key,
}
}
if host.jabber_id:
host_json['data']['jabberId'] = host.jabber_id
post_data = json.dumps(host_json)
self._http.request("POST", self._base_url, post_data, self._headers)
response = self._http.getresponse()
if response.status != 200:
raise HostDirectoryError(response.reason, response.read())
data = response.read()
def get_hosts(self):
self._http.request("GET", self._base_url, headers=self._headers)
response = self._http.getresponse()
if response.status != 200:
raise HostDirectoryError(response.reason, response.read())
data = response.read()
data = json.loads(data)[u'data']
results = []
if data.has_key(u'items'):
for item in data[u'items']:
results.append(Host(item))
return results
def delete_host(self, host_id):
url = self._base_url + '/' + host_id
self._http.request("DELETE", url, headers=self._headers)
response = self._http.getresponse()
if response.status / 100 != 2: # Normally 204 is returned
raise HostDirectoryError(response.reason, response.read())
data = response.read()
def usage():
sys.stderr.write(
("Usage:\n" +
" Login: \t\t%(cmd)s login\n" +
" Register host: \t%(cmd)s insert --hostId=<hostId>" +
" --hostName=<hostName> \\\n" +
"\t\t\t --publicKey=<publicKey> --jabberId=<jabberId>\n" +
" List hosts: \t\t%(cmd)s list\n" +
" Delete a host: \t%(cmd)s delete <host_id>\n")
% {"cmd" : sys.argv[0]})
return 1
class CommandError(Exception):
def __init__(self, message):
Exception.__init__(self, message)
def load_auth_token():
try:
lines = open(auth_filepath).readlines()
except IOError:
raise CommandError(("Can't open file (%s). Please run " +
"'%s login' and try again.") %
(auth_filepath, sys.argv[0]))
if len(lines) != 2:
raise CommandError(("Invalid auth file (%s). Please run " +
"'%s login' and try again.") %
(auth_filepath, sys.argv[0]))
return map(lambda x: x.strip(), lines)
def login_cmd(args):
"""login command"""
if len(args) != 0:
return usage()
import getpass
import gaia_auth
print "Email:",
email = raw_input()
passwd = getpass.getpass("Password: ")
authenticator = gaia_auth.GaiaAuthenticator('chromoting');
auth_token = authenticator.authenticate(email, passwd)
# Set permission mask for created file.
os.umask(0066)
auth_file = open(auth_filepath, 'w')
auth_file.write(email)
auth_file.write('\n')
auth_file.write(auth_token)
auth_file.close()
print 'Auth token: ', auth_token
print '...saved in', auth_filepath
def list_cmd(args):
"""list command"""
if len(args) != 0:
return usage()
(username, token) = load_auth_token()
client = HostDirectory(username, token)
print '%36s %30s %s' % ("HOST ID", "HOST NAME", "JABBER ID")
for host in client.get_hosts():
print '%36s %30s %s' % (host.host_id, host.host_name, host.jabber_id)
return 0
def insert_cmd(args):
"""insert command"""
(username, token) = load_auth_token()
client = HostDirectory(username, token)
host = Host()
for arg in args:
if arg.startswith("--hostId="):
host.host_id = arg[len("--hostId="):]
elif arg.startswith("--hostName="):
host.host_name = arg[len("--hostName="):]
elif arg.startswith("--publicKey="):
host.public_key = arg[len("--publicKey="):]
elif arg.startswith("--jabberId="):
host.jabber_id = arg[len("--jabberId="):]
else:
return usage()
client.add_host(host)
return 0
def delete_cmd(args):
"""delete command"""
if len(args) != 1:
return usage()
host_id = args[0]
(username, token) = load_auth_token()
client = HostDirectory(username, token)
client.delete_host(host_id)
return 0
def main():
import sys
args = sys.argv[1:]
if len(args) == 0:
return usage()
command = args[0]
try:
if command == "help":
usage()
elif command == "login":
return login_cmd(args[1:])
elif command == "list":
return list_cmd(args[1:])
elif command == "insert":
return insert_cmd(args[1:])
elif command == "delete":
return delete_cmd(args[1:])
else:
raise CommandError("Unknown command: %s" % command);
except CommandError as e:
sys.stderr.write("%s\n" % e.args[0])
return 1
return 0
if __name__ == '__main__':
sys.exit(main())