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.
7 # Chromoting Directory API client implementation. Used for testing/debugging
8 # purposes. Requires Python 2.6: json module is not available in earlier
19 DEFAULT_DIRECTORY_SERVER
= 'www.googleapis.com'
21 auth_filepath
= os
.path
.join(os
.path
.expanduser('~'),
22 '.chromotingDirectoryAuthToken')
25 return ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x" %
26 tuple(map(lambda x
: random
.randrange(0,65536), range(8))))
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")
40 self
.host_id
= random_uuid()
42 self
.host_name
= socket
.gethostname()
43 self
.public_key
= None
45 self
.created_time
= None
46 self
.updated_time
= None
49 class HostDirectoryError(Exception):
50 def __init__(self
, message
, response
):
51 Exception.__init
__(self
, message
)
53 self
._response
= response
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'
61 self
._http
= httplib
.HTTPSConnection(server
)
62 self
._headers
= {"Authorization": "GoogleLogin auth=" + self
._auth
_token
,
63 "Content-Type": "application/json" }
65 def add_host(self
, host
):
67 { 'hostId': host
.host_id
,
68 'hostName': host
.host_name
,
69 'publicKey': host
.public_key
,
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()
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']
89 if data
.has_key(u
'items'):
90 for item
in data
[u
'items']:
91 results
.append(Host(item
))
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()
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]})
114 class CommandError(Exception):
115 def __init__(self
, message
):
116 Exception.__init
__(self
, message
)
118 def load_auth_token():
120 lines
= open(auth_filepath
).readlines()
122 raise CommandError("Can't open file (%s). Please run " +
123 "'%s login' and try again." %
124 (auth_filepath
, sys
.argv
[0]))
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
)
141 passwd
= getpass
.getpass("Password: ")
143 authenticator
= gaia_auth
.GaiaAuthenticator('chromoting');
144 auth_token
= authenticator
.authenticate(email
, passwd
)
146 # Set permission mask for created file.
148 auth_file
= open(auth_filepath
, 'w')
149 auth_file
.write(email
)
150 auth_file
.write('\n')
151 auth_file
.write(auth_token
)
154 print 'Auth token: ', auth_token
155 print '...saved in', auth_filepath
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
)
168 def insert_cmd(args
):
170 (username
, token
) = load_auth_token()
171 client
= HostDirectory(username
, token
)
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="):]
186 client
.add_host(host
)
189 def delete_cmd(args
):
194 (username
, token
) = load_auth_token()
195 client
= HostDirectory(username
, token
)
196 client
.delete_host(host_id
)
207 if command
== "help":
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:])
218 raise CommandError("Unknown command: %s" % command
);
220 except CommandError
as e
:
221 sys
.stderr
.write("%s\n" % e
.args
[0])
226 if __name__
== '__main__':