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