- add sources.
[platform/framework/web/crosswalk.git] / src / tools / telemetry / telemetry / core / browser_credentials.py
1 # Copyright (c) 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.
4
5 import logging
6 import json
7 import os
8
9 from telemetry.core import util
10 from telemetry.core.backends import facebook_credentials_backend
11 from telemetry.core.backends import google_credentials_backend
12 from telemetry.unittest import options_for_unittests
13
14
15 class BrowserCredentials(object):
16   def __init__(self, backends = None):
17     self._credentials = {}
18     self._credentials_path = None
19     self._extra_credentials = {}
20
21     if backends is None:
22       backends = [
23         facebook_credentials_backend.FacebookCredentialsBackend(),
24         google_credentials_backend.GoogleCredentialsBackend()]
25
26     self._backends = {}
27     for backend in backends:
28       self._backends[backend.credentials_type] = backend
29
30   def AddBackend(self, backend):
31     assert backend.credentials_type not in self._backends
32     self._backends[backend.credentials_type] = backend
33
34   def IsLoggedIn(self, credentials_type):
35     if credentials_type not in self._backends:
36       raise Exception('Unrecognized credentials type: %s', credentials_type)
37     if credentials_type not in self._credentials:
38       return False
39     return self._backends[credentials_type].IsLoggedIn()
40
41   def CanLogin(self, credentials_type):
42     if credentials_type not in self._backends:
43       raise Exception('Unrecognized credentials type: %s', credentials_type)
44     return credentials_type in self._credentials
45
46   def LoginNeeded(self, tab, credentials_type):
47     if credentials_type not in self._backends:
48       raise Exception('Unrecognized credentials type: %s', credentials_type)
49     if credentials_type not in self._credentials:
50       return False
51     return self._backends[credentials_type].LoginNeeded(
52       tab, self._credentials[credentials_type])
53
54   def LoginNoLongerNeeded(self, tab, credentials_type):
55     assert credentials_type in self._backends
56     self._backends[credentials_type].LoginNoLongerNeeded(tab)
57
58   @property
59   def credentials_path(self):
60     return self._credentials_path
61
62   @credentials_path.setter
63   def credentials_path(self, credentials_path):
64     self._credentials_path = credentials_path
65     self._RebuildCredentials()
66
67   def Add(self, credentials_type, data):
68     if credentials_type not in self._extra_credentials:
69       self._extra_credentials[credentials_type] = {}
70     for k, v in data.items():
71       assert k not in self._extra_credentials[credentials_type]
72       self._extra_credentials[credentials_type][k] = v
73     self._RebuildCredentials()
74
75   def _ResetLoggedInState(self):
76     """Makes the backends think we're not logged in even though we are.
77     Should only be used in unit tests to simulate --dont-override-profile.
78     """
79     for backend in self._backends.keys():
80       self._backends[backend]._ResetLoggedInState() # pylint: disable=W0212
81
82   def _RebuildCredentials(self):
83     credentials = {}
84     if self._credentials_path == None:
85       pass
86     elif os.path.exists(self._credentials_path):
87       with open(self._credentials_path, 'r') as f:
88         credentials = json.loads(f.read())
89
90     # TODO(nduca): use system keychain, if possible.
91     homedir_credentials_path = os.path.expanduser('~/.telemetry-credentials')
92     homedir_credentials = {}
93
94     if (not options_for_unittests.GetCopy() and
95         os.path.exists(homedir_credentials_path)):
96       logging.info("Found ~/.telemetry-credentials. Its contents will be used "
97                    "when no other credentials can be found.")
98       with open(homedir_credentials_path, 'r') as f:
99         homedir_credentials = json.loads(f.read())
100
101     self._credentials = {}
102     all_keys = set(credentials.keys()).union(
103       homedir_credentials.keys()).union(
104       self._extra_credentials.keys())
105
106     for k in all_keys:
107       if k in credentials:
108         self._credentials[k] = credentials[k]
109       if k in homedir_credentials:
110         logging.info("Will use ~/.telemetry-credentials for %s logins." % k)
111         self._credentials[k] = homedir_credentials[k]
112       if k in self._extra_credentials:
113         self._credentials[k] = self._extra_credentials[k]
114
115   def WarnIfMissingCredentials(self, page_set):
116     num_pages_missing_login = 0
117     missing_credentials = set()
118     for page in page_set:
119       if (page.credentials
120           and not self.CanLogin(page.credentials)):
121         num_pages_missing_login += 1
122         missing_credentials.add(page.credentials)
123
124     if num_pages_missing_login > 0:
125       files_to_tweak = []
126       if page_set.credentials_path:
127         files_to_tweak.append(
128           os.path.relpath(os.path.join(os.path.dirname(page_set.file_path),
129                                        page_set.credentials_path)))
130       files_to_tweak.append('~/.telemetry-credentials')
131
132       example_credentials_file = os.path.join(
133           util.GetTelemetryDir(), 'examples', 'credentials_example.json')
134
135       logging.warning("""
136         Credentials for %s were not found. %i pages will not be tested.
137
138         To fix this, either add svn-internal to your .gclient using
139         http://goto/read-src-internal, or add your own credentials to:
140             %s
141         An example credentials file you can copy from is here:
142             %s\n""" % (', '.join(missing_credentials),
143          num_pages_missing_login,
144          ' or '.join(files_to_tweak),
145          example_credentials_file))