browser_credentials.py revision 424c4d7b64af9d0d8fd9624f381f469654d5e3d2
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 5import logging 6import json 7import os 8 9from telemetry.core import util 10from telemetry.core.backends import facebook_credentials_backend 11from telemetry.core.backends import google_credentials_backend 12from telemetry.unittest import options_for_unittests 13 14 15class 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)) 146