form_based_credentials_backend.py revision 424c4d7b64af9d0d8fd9624f381f469654d5e3d2
1424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)# Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import logging 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from telemetry.core import util 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)def _WaitForLoginFormToLoad(backend, login_form_id, tab): 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def IsFormLoadedOrAlreadyLoggedIn(): 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return tab.EvaluateJavaScript( 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'document.querySelector("#%s")!== null' % login_form_id) or \ 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) backend.IsAlreadyLoggedIn(tab) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Wait until the form is submitted and the page completes loading. 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) util.WaitFor(lambda: IsFormLoadedOrAlreadyLoggedIn(), # pylint: disable=W0108 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 60) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def _SubmitFormAndWait(form_id, tab): 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) js = 'document.getElementById("%s").submit();' % form_id 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab.ExecuteJavaScript(js) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def IsLoginStillHappening(): 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return tab.EvaluateJavaScript( 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'document.querySelector("#%s")!== null' % form_id) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Wait until the form is submitted and the page completes loading. 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) util.WaitFor(lambda: not IsLoginStillHappening(), 60) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FormBasedCredentialsBackend(object): 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self): 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._logged_in = False 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def IsAlreadyLoggedIn(self, tab): 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) raise NotImplementedError() 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) @property 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def credentials_type(self): 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise NotImplementedError() 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) @property 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def url(self): 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise NotImplementedError() 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) @property 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def login_form_id(self): 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise NotImplementedError() 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) @property 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def login_input_id(self): 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise NotImplementedError() 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) @property 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def password_input_id(self): 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise NotImplementedError() 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def IsLoggedIn(self): 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self._logged_in 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _ResetLoggedInState(self): 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Makes the backend think we're not logged in even though we are. 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Should only be used in unit tests to simulate --dont-override-profile. 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._logged_in = False 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def LoginNeeded(self, tab, config): 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Logs in to a test account. 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Raises: 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RuntimeError: if could not get credential information. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self._logged_in: 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return True 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if 'username' not in config or 'password' not in config: 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message = ('Credentials for "%s" must include username and password.' % 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.credentials_type) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise RuntimeError(message) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging.debug('Logging into %s account...' % self.credentials_type) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging.info('Loading %s...', self.url) 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab.Navigate(self.url) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) _WaitForLoginFormToLoad(self, self.login_form_id, tab) 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if self.IsAlreadyLoggedIn(tab): 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._logged_in = True 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return True 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab.WaitForDocumentReadyStateToBeInteractiveOrBetter() 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging.info('Loaded page: %s', self.url) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) email_id = 'document.querySelector("#%s").%s.value = "%s"; ' % ( 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self.login_form_id, self.login_input_id, config['username']) 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) password = 'document.querySelector("#%s").%s.value = "%s"; ' % ( 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self.login_form_id, self.password_input_id, config['password']) 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab.ExecuteJavaScript(email_id) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab.ExecuteJavaScript(password) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) _SubmitFormAndWait(self.login_form_id, tab) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._logged_in = True 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return True 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) except util.TimeoutException: 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging.warning('Timed out while loading: %s', self.url) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return False 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def LoginNoLongerNeeded(self, tab): # pylint: disable=W0613 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert self._logged_in 111