def test_browser_authorize(self, new_state_mock, quickstart_mock, open_mock): """ Test that the browser_authorize method opens a browser to the right URL and starts the CherryPy server to listen for a redirect """ # Mock the state generation function so we know what it returns new_state_mock.return_value = self.state auth = MisfitAuth(self.client_id, self.client_secret, **self.kwargs) auth.browser_authorize() open_mock.assert_called_once_with(auth.authorize_url()) quickstart_mock.assert_called_once_with(auth)
def test_init(self): """ Test all the ways we can create a MisfitAuth object """ # Only mandatory args auth = MisfitAuth(self.client_id, self.client_secret) self._verify_member_vars(auth) # Override args auth = MisfitAuth(self.client_id, self.client_secret, **self.kwargs) self._verify_member_vars(auth, **self.kwargs) # Check that a new state doesn't get generated to override the value # passed auth.authorize_url() self.assertEqual(auth.state, self.state)
def test_authorize_url(self, new_state_mock): """ Test that the authorize_url method sets the state and returns the right url """ auth = MisfitAuth(self.client_id, self.client_secret, **self.kwargs) # Mock the state generation function so we know what it returns new_state_mock.return_value = self.state self.assertEqual(auth.authorize_url(), API_URL + ( r'auth/dialog/authorize?response_type=code&' 'client_id=FAKE_CLIENT_ID&' 'redirect_uri=http%3A%2F%2Fwww.example.com%2Fmisfit-auth%2F&' 'scope=public&state=FAKE_STATE')) self.assertEqual(auth.state, self.state)
def authorize(self): """ Authorize a user using the browser and a CherryPy server, and write the resulting credentials to a config file. """ # Thanks to the magic of docopts, I can be guaranteed to have a # a client_id and client_secret auth = MisfitAuth(self.client_id, self.client_secret) auth.browser_authorize() # Write the authentication information to a config file for later use if auth.token: self.write_config(auth.token['access_token']) else: print('ERROR: We were unable to authorize to use the Misfit API.')
def test_fetch_token(self, fetch_token_mock, new_state_mock): """ Test that the fetch_token method gets the access_token and checks for mismatching state """ auth = MisfitAuth(self.client_id, self.client_secret, **self.kwargs) # Mock the fetch_token function so we don't actually hit the API fetch_token_mock.return_value = self.token # Mock the state generation function so we know what it returns new_state_mock.return_value = self.state auth.authorize_url() self.assertEqual(auth.fetch_token(self.code, self.state), self.access_token) self.assertEqual(auth.token, self.token) fetch_token_mock.assert_called_once_with( '%sauth/tokens/exchange/' % API_URL, client_secret='FAKE_CLIENT_SECRET', code=self.code) # Try with a bad state self.assertRaises(MismatchingStateError, auth.fetch_token, self.code, 'BAD_STATE')
def test_shutdown_cherrypy(self, timer_mock): """ Test that the _shutdown_cherrypy method shuts down the cherrypy server if it's running. """ # No shutdown if the server isn't running auth = MisfitAuth(self.client_id, self.client_secret, **self.kwargs) auth._shutdown_cherrypy() self.assertEqual(timer_mock().start.call_count, 0) # Make sure the server shuts down, if it is running auth = MisfitAuth(self.client_id, self.client_secret, **self.kwargs) cherrypy.engine.state = cherrypy.engine.states.STARTED auth._shutdown_cherrypy() timer_mock().start.assert_called_once_with()
def test_index(self, new_state_mock, fetch_token_mock, timer_mock): """ Test that the index CherryPy endpoint fetches the access_token and then shuts down the CherryPy server """ auth = MisfitAuth(self.client_id, self.client_secret, **self.kwargs) # Mock the fetch_token function so we don't actually hit the API fetch_token_mock.return_value = self.token # Mock the state generation function so we know what it returns new_state_mock.return_value = self.state auth.authorize_url() self.assertEqual(auth.index(self.code, self.state), self.kwargs['html']) self.assertEqual(auth.token, self.token) fetch_token_mock.assert_called_once_with( '%sauth/tokens/exchange/' % API_URL, client_secret='FAKE_CLIENT_SECRET', code='FAKE_CODE') self.assertEqual(timer_mock.call_count, 1) timer_mock().start.assert_called_once_with() # Also try with an invalid state self.assertRaises(MismatchingStateError, auth.index, self.code, 'BAD_STATE')
def test_shutdown_cherrypy(self, exit_mock): """ Test that the _shutdown_cherrypy method shuts down the cherrypy server if it's running. """ # No shutdown if the server isn't running auth = MisfitAuth(self.client_id, self.client_secret, **self.kwargs) with patch('threading.Timer') as timer_mock: auth._shutdown_cherrypy() self.assertEqual(timer_mock().start.call_count, 0) self.assertEqual(exit_mock.call_count, 0) # Make sure the server shuts down, if it is running auth = MisfitAuth(self.client_id, self.client_secret, **self.kwargs) cherrypy.engine.state = cherrypy.engine.states.STARTED with self.wait_for_thread(exit_mock): auth._shutdown_cherrypy() self.assertEqual(exit_mock.call_count, 1) exit_mock.assert_called_once_with()
def test_index(self, new_state_mock, fetch_token_mock, timer_mock): """ Test that the index CherryPy endpoint fetches the access_token and then shuts down the CherryPy server """ # Mock the fetch_token function so we don't actually hit the API fetch_token_mock.return_value = self.token # Mock the state generation function so we know what it returns new_state_mock.return_value = self.state auth = MisfitAuth(self.client_id, self.client_secret, **self.kwargs) auth.authorize_url() cherrypy.engine.state = cherrypy.engine.states.STARTED self.assertEqual(auth.index(self.state, code=self.code), self.kwargs['success_html']) self.assertEqual(auth.token, self.token) fetch_token_mock.assert_called_once_with( '%sauth/tokens/exchange/' % API_URL, client_secret='FAKE_CLIENT_SECRET', code=self.code) timer_mock().start.assert_called_once_with() # Try with an error timer_mock.reset_mock() fetch_token_mock.reset_mock() auth = MisfitAuth(self.client_id, self.client_secret, **self.kwargs) auth.authorize_url() self.assertEqual( auth.index(self.state, error='access_denied'), self.kwargs['failure_html'] % ('Unknown error while authenticating', '')) assert auth.token is None self.assertEqual(fetch_token_mock.call_count, 0) timer_mock().start.assert_called_once_with() # Also try with an invalid state timer_mock.reset_mock() fetch_token_mock.reset_mock() auth = MisfitAuth(self.client_id, self.client_secret, **self.kwargs) auth.authorize_url() assert auth.index('BAD_STATE', code=self.code).startswith( self.kwargs['failure_html'] % ('CSRF Warning! Mismatching state', '')) assert auth.token is None self.assertEqual(fetch_token_mock.call_count, 0) timer_mock().start.assert_called_once_with() # Also try with an a bad client_secret timer_mock.reset_mock() fetch_token_mock.reset_mock() fetch_token_mock.side_effect = MissingTokenError auth = MisfitAuth(self.client_id, 'INVALID_SECRET', **self.kwargs) auth.authorize_url() assert auth.index(self.state, code=self.code).startswith( self.kwargs['failure_html'] % ('Missing access token parameter.</br>Please check ' 'that you are using the correct client_secret', '')) assert auth.token is None self.assertEqual(fetch_token_mock.call_count, 1) timer_mock().start.assert_called_once_with()
def test_index(self, new_state_mock, fetch_token_mock, timer_mock): """ Test that the index CherryPy endpoint fetches the access_token and then shuts down the CherryPy server """ auth = MisfitAuth(self.client_id, self.client_secret, **self.kwargs) # Mock the fetch_token function so we don't actually hit the API fetch_token_mock.return_value = self.token # Mock the state generation function so we know what it returns new_state_mock.return_value = self.state auth.authorize_url() cherrypy.engine.state = cherrypy.engine.states.STARTED self.assertEqual(auth.index(self.state, code=self.code), self.kwargs['success_html']) self.assertEqual(auth.token, self.token) fetch_token_mock.assert_called_once_with( '%sauth/tokens/exchange/' % API_URL, client_secret='FAKE_CLIENT_SECRET', code=self.code) timer_mock().start.assert_called_once_with() # Try with an error timer_mock.reset_mock() fetch_token_mock.reset_mock() auth = MisfitAuth(self.client_id, self.client_secret, **self.kwargs) auth.authorize_url() self.assertEqual(auth.index(self.state, error='access_denied'), self.kwargs['failure_html']) assert auth.token is None self.assertEqual(fetch_token_mock.call_count, 0) timer_mock().start.assert_called_once_with() # Also try with an invalid state timer_mock.reset_mock() fetch_token_mock.reset_mock() auth = MisfitAuth(self.client_id, self.client_secret, **self.kwargs) auth.authorize_url() self.assertRaises(MismatchingStateError, auth.index, 'BAD_STATE', code=self.code) assert auth.token is None self.assertEqual(fetch_token_mock.call_count, 0) timer_mock().start.assert_called_once_with()
def test_index(self, new_state_mock, fetch_token_mock, timer_mock): """ Test that the index CherryPy endpoint fetches the access_token and then shuts down the CherryPy server """ # Mock the fetch_token function so we don't actually hit the API fetch_token_mock.return_value = self.token # Mock the state generation function so we know what it returns new_state_mock.return_value = self.state auth = MisfitAuth(self.client_id, self.client_secret, **self.kwargs) auth.authorize_url() cherrypy.engine.state = cherrypy.engine.states.STARTED self.assertEqual(auth.index(self.state, code=self.code), self.kwargs['success_html']) self.assertEqual(auth.token, self.token) fetch_token_mock.assert_called_once_with( '%sauth/tokens/exchange/' % API_URL, client_secret='FAKE_CLIENT_SECRET', code=self.code) timer_mock().start.assert_called_once_with() # Try with an error timer_mock.reset_mock() fetch_token_mock.reset_mock() auth = MisfitAuth(self.client_id, self.client_secret, **self.kwargs) auth.authorize_url() self.assertEqual(auth.index(self.state, error='access_denied'), self.kwargs['failure_html'] % ('Unknown error while authenticating', '')) assert auth.token is None self.assertEqual(fetch_token_mock.call_count, 0) timer_mock().start.assert_called_once_with() # Also try with an invalid state timer_mock.reset_mock() fetch_token_mock.reset_mock() auth = MisfitAuth(self.client_id, self.client_secret, **self.kwargs) auth.authorize_url() assert auth.index('BAD_STATE', code=self.code).startswith( self.kwargs['failure_html'] % ('CSRF Warning! Mismatching state', '')) assert auth.token is None self.assertEqual(fetch_token_mock.call_count, 0) timer_mock().start.assert_called_once_with() # Also try with an a bad client_secret timer_mock.reset_mock() fetch_token_mock.reset_mock() fetch_token_mock.side_effect = MissingTokenError auth = MisfitAuth(self.client_id, 'INVALID_SECRET', **self.kwargs) auth.authorize_url() assert auth.index(self.state, code=self.code).startswith( self.kwargs['failure_html'] % ('Missing access token parameter.</br>Please check ' 'that you are using the correct client_secret', '')) assert auth.token is None self.assertEqual(fetch_token_mock.call_count, 1) timer_mock().start.assert_called_once_with()