1 # Copyright 2012 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.
9 from telemetry.core import util
10 from telemetry.core.backends import codepen_credentials_backend
11 from telemetry.core.backends import facebook_credentials_backend
12 from telemetry.core.backends import google_credentials_backend
13 from telemetry.page.actions import action_runner
14 from telemetry.unittest import options_for_unittests
17 class CredentialsError(Exception):
18 """Error that can be thrown when logging in."""
21 class BrowserCredentials(object):
22 def __init__(self, backends = None):
23 self._credentials = {}
24 self._credentials_path = None
25 self._extra_credentials = {}
29 codepen_credentials_backend.CodePenCredentialsBackend(),
30 facebook_credentials_backend.FacebookCredentialsBackend(),
31 facebook_credentials_backend.FacebookCredentialsBackend2(),
32 google_credentials_backend.GoogleCredentialsBackend()]
35 for backend in backends:
36 self._backends[backend.credentials_type] = backend
38 def AddBackend(self, backend):
39 assert backend.credentials_type not in self._backends
40 self._backends[backend.credentials_type] = backend
42 def IsLoggedIn(self, credentials_type):
43 if credentials_type not in self._backends:
44 raise CredentialsError(
45 'Unrecognized credentials type: %s', credentials_type)
46 if credentials_type not in self._credentials:
48 return self._backends[credentials_type].IsLoggedIn()
50 def CanLogin(self, credentials_type):
51 if credentials_type not in self._backends:
52 raise CredentialsError(
53 'Unrecognized credentials type: %s', credentials_type)
54 return credentials_type in self._credentials
56 def LoginNeeded(self, tab, credentials_type):
57 if credentials_type not in self._backends:
58 raise CredentialsError(
59 'Unrecognized credentials type: %s', credentials_type)
60 if credentials_type not in self._credentials:
62 runner = action_runner.ActionRunner(tab)
63 return self._backends[credentials_type].LoginNeeded(
64 tab, runner, self._credentials[credentials_type])
66 def LoginNoLongerNeeded(self, tab, credentials_type):
67 assert credentials_type in self._backends
68 self._backends[credentials_type].LoginNoLongerNeeded(tab)
71 def credentials_path(self): # pylint: disable=E0202
72 return self._credentials_path
74 @credentials_path.setter
75 def credentials_path(self, credentials_path): # pylint: disable=E0202
76 self._credentials_path = credentials_path
77 self._RebuildCredentials()
79 def Add(self, credentials_type, data):
80 if credentials_type not in self._extra_credentials:
81 self._extra_credentials[credentials_type] = {}
82 for k, v in data.items():
83 assert k not in self._extra_credentials[credentials_type]
84 self._extra_credentials[credentials_type][k] = v
85 self._RebuildCredentials()
87 def _ResetLoggedInState(self):
88 """Makes the backends think we're not logged in even though we are.
89 Should only be used in unit tests to simulate --dont-override-profile.
91 for backend in self._backends.keys():
92 self._backends[backend]._ResetLoggedInState() # pylint: disable=W0212
94 def _RebuildCredentials(self):
96 if self._credentials_path == None:
98 elif os.path.exists(self._credentials_path):
99 with open(self._credentials_path, 'r') as f:
100 credentials = json.loads(f.read())
102 # TODO(nduca): use system keychain, if possible.
103 homedir_credentials_path = os.path.expanduser('~/.telemetry-credentials')
104 homedir_credentials = {}
106 if (not options_for_unittests.GetCopy() and
107 os.path.exists(homedir_credentials_path)):
108 logging.info("Found ~/.telemetry-credentials. Its contents will be used "
109 "when no other credentials can be found.")
110 with open(homedir_credentials_path, 'r') as f:
111 homedir_credentials = json.loads(f.read())
113 self._credentials = {}
114 all_keys = set(credentials.keys()).union(
115 homedir_credentials.keys()).union(
116 self._extra_credentials.keys())
120 self._credentials[k] = credentials[k]
121 if k in homedir_credentials:
122 logging.info("Will use ~/.telemetry-credentials for %s logins." % k)
123 self._credentials[k] = homedir_credentials[k]
124 if k in self._extra_credentials:
125 self._credentials[k] = self._extra_credentials[k]
127 def WarnIfMissingCredentials(self, page):
128 if (page.credentials and not self.CanLogin(page.credentials)):
130 if page.credentials_path:
131 files_to_tweak.append(page.credentials_path)
132 files_to_tweak.append('~/.telemetry-credentials')
134 example_credentials_file = os.path.join(
135 util.GetTelemetryDir(), 'examples', 'credentials_example.json')
138 Credentials for %s were not found. page %s will not be tested.
140 To fix this, either follow the instructions to authenticate to gsutil
142 http://www.chromium.org/developers/telemetry/upload_to_cloud_storage,
144 or add your own credentials to:
146 An example credentials file you can copy from is here:
147 %s\n""" % (page.credentials, page, ' or '.join(files_to_tweak),
148 example_credentials_file))