f7f4b44e458dc8997a0d8801d0a86c1fd516b875
[platform/framework/web/crosswalk.git] / src / tools / swarming_client / auth.py
1 #!/usr/bin/env python
2 # Copyright 2013 The Swarming Authors. All rights reserved.
3 # Use of this source code is governed under the Apache License, Version 2.0 that
4 # can be found in the LICENSE file.
5
6 """Client tool to perform various authentication related tasks."""
7
8 __version__ = '0.3'
9
10 import optparse
11 import sys
12
13 from third_party import colorama
14 from third_party.depot_tools import fix_encoding
15 from third_party.depot_tools import subcommand
16
17 from utils import net
18 from utils import oauth
19 from utils import tools
20
21
22 def add_auth_options(parser):
23   """Adds command line options related to authentication."""
24   parser.auth_group = optparse.OptionGroup(parser, 'Authentication')
25   parser.auth_group.add_option(
26       '--use-cookie-auth', action='store_true',
27       help='Use cookie-based authentication instead of OAuth.')
28   parser.add_option_group(parser.auth_group)
29   oauth.add_oauth_options(parser)
30
31
32 def process_auth_options(options):
33   """Configures process-wide authentication parameters based on |options|."""
34   method = 'cookie' if options.use_cookie_auth else 'oauth'
35   net.configure_auth(method, oauth_options=options)
36
37
38 class AuthServiceError(Exception):
39   """Unexpected response from authentication service."""
40
41
42 class AuthService(object):
43   """Represents remote Authentication service."""
44
45   def __init__(self, url):
46     self._service = net.get_http_service(url)
47
48   def login(self):
49     """Refreshes cached access token or creates a new one."""
50     return self._service.login()
51
52   def logout(self):
53     """Purges cached access token."""
54     return self._service.logout()
55
56   def get_current_identity(self):
57     """Returns identity associated with currently used credentials.
58
59     Identity is a string:
60       user:<email> - if using OAuth or cookie based authentication.
61       bot:<id> - if using HMAC based authentication.
62       anonymous:anonymous - if not authenticated.
63     """
64     identity = self._service.json_request('GET', '/auth/api/v1/accounts/self')
65     if not identity:
66       raise AuthServiceError('Failed to fetch identity')
67     return identity['identity']
68
69
70 @subcommand.usage('[options]')
71 def CMDlogin(parser, args):
72   """Refreshes short lived authentication token."""
73   (options, args) = parser.parse_args(args)
74   process_auth_options(options)
75   service = AuthService(options.service)
76   if service.login():
77     print 'Logged in as \'%s\'.' % service.get_current_identity()
78     return 0
79   else:
80     print 'Login failed or canceled.'
81     return 1
82
83
84 @subcommand.usage('[options]')
85 def CMDlogout(parser, args):
86   """Purges cached credentials."""
87   (options, args) = parser.parse_args(args)
88   process_auth_options(options)
89   service = AuthService(options.service)
90   service.logout()
91
92
93 @subcommand.usage('[options]')
94 def CMDcheck(parser, args):
95   """Shows identity associated with currently cached credentials."""
96   (options, args) = parser.parse_args(args)
97   process_auth_options(options)
98   service = AuthService(options.service)
99   print service.get_current_identity()
100
101
102 class OptionParserAuth(tools.OptionParserWithLogging):
103   def __init__(self, **kwargs):
104     tools.OptionParserWithLogging.__init__(self, prog='auth.py', **kwargs)
105     self.server_group = tools.optparse.OptionGroup(self, 'Server')
106     self.server_group.add_option(
107         '-S', '--service',
108         metavar='URL', default='',
109         help='Service to use')
110     self.add_option_group(self.server_group)
111     add_auth_options(self)
112
113   def parse_args(self, *args, **kwargs):
114     options, args = tools.OptionParserWithLogging.parse_args(
115         self, *args, **kwargs)
116     options.service = options.service.rstrip('/')
117     if not options.service:
118       self.error('--service is required.')
119     return options, args
120
121
122 def main(args):
123   dispatcher = subcommand.CommandDispatcher(__name__)
124   try:
125     return dispatcher.execute(OptionParserAuth(version=__version__), args)
126   except Exception as e:
127     tools.report_error(e)
128     return 1
129
130
131 if __name__ == '__main__':
132   fix_encoding.fix_encoding()
133   tools.disable_buffering()
134   colorama.init()
135   sys.exit(main(sys.argv[1:]))