def test_deauthorization_url(self): with mock.patch.object(HealthVaultConn, '_get_auth_token'): c = HealthVaultConn(app_id="123", app_thumbprint="2", public_key=TEST_PUBLIC_KEY, private_key=TEST_PRIVATE_KEY, wctoken=None, server="6", shell_server="shell.server") c.auth_token = "FakeToken" url = c.deauthorization_url( "http://ourown.server.com/with/some/parts/") self.assertIsNotNone( re. compile('https://shell\.server/redirect\.aspx\?[{0}&{0}]'.format( '(targetqs=redirect%3D' 'http%253A%252F%252Fourown\.server\.com%252Fwith%252Fsome%252Fparts%25' '2F%26cred_token%3DFakeToken%26appid%3D123)|(target=APPSIGNOUT)' )).match(url)) # callback URL is optional url = c.deauthorization_url() self.assertIsNotNone( url, 'https://shell\.server/redirect\.aspx\?[{0}&{0}]'.format( '(targetqs=cred_token%3D' 'FakeToken%26appid%3D123)|(target=APPSIGNOUT)'))
def test_connect(self): # If we build a conn without a wctoken, it doesn't do the connect # though it does get a session token # then we can call connect with a wctoken and it'll do it then with mock.patch.object(HealthVaultConn, '_get_auth_token') as gat: with mock.patch.object(HealthVaultConn, '_get_record_id') as gri: gri.return_value = 1 c = HealthVaultConn(app_id="1", app_thumbprint="2", public_key=TEST_PUBLIC_KEY, private_key=TEST_PRIVATE_KEY, wctoken=None, server="6", shell_server="7") self.assertIsNone(c.wctoken) self.assertFalse(c.is_authorized()) gat.assert_any_call() self.assertFalse(gri.called) self.assertIsNotNone(c.auth_token) with mock.patch.object(HealthVaultConn, '_get_auth_token') as gat: with mock.patch.object(HealthVaultConn, '_get_record_id') as gri: gri.return_value = 8 c.connect(wctoken="5") self.assertEqual("5", c.wctoken) gri.assert_any_call() self.assertTrue(c.is_authorized())
def verify_get_data_api(self, xml, expected, methodname): """Given one of the methods that gets some XML from HealthVault and returns a dictionary or list, verify it returns what we expect :param xml: The XML that get_things will return to the method under test :param expected: The expected return value of the method under test :param methodname: The name of the method under test """ # construct a conn, mocking all the real work with mock.patch.object(HealthVaultConn, '_get_auth_token') as gat: gat.return_value = "authtoken" with mock.patch.object(HealthVaultConn, '_get_record_id') as gri: gri.return_value = "1" c = HealthVaultConn(app_id="1", app_thumbprint="2", public_key=TEST_PUBLIC_KEY, private_key=TEST_PRIVATE_KEY, wctoken="5", server="6", shell_server="7") # call the method under test, mocking the actual network call with mock.patch.object(HealthVaultConn, '_build_and_send_request') as basr: # convert the xml we were given (top element is <info>) to look like what HealthVault would return full_xml_response = '<?xml version="1.0" encoding="ISO-8859-1"?><unneededtag>' + xml + "</unneededtag>" basr.return_value = (None, full_xml_response, ET.fromstring(full_xml_response)) method_to_test = getattr(c, methodname) retval = method_to_test() self.assertEqual(expected, retval)
def test_build_and_send_request(self): # construct a conn, mocking all the real work AUTH_TOKEN = "AUTHKEY" WC_TOKEN = "WCKEY" with mock.patch.object(HealthVaultConn, '_get_auth_token') as gat: with mock.patch.object(HealthVaultConn, '_get_record_id') as gri: gat.return_value = AUTH_TOKEN gri.return_value = "8" c = HealthVaultConn(app_id="1", app_thumbprint="2", public_key=TEST_PUBLIC_KEY, private_key=TEST_PRIVATE_KEY, wctoken=WC_TOKEN, server="6", shell_server="7") with mock.patch.object(c, '_send_request') as sendRequest: c._build_and_send_request(method_name="METHOD", info="<info>BOO</info>") payload = sendRequest.call_args[0][0] request = ET.fromstring(payload) # print elt_to_string(request) header = request.find('header') method_name = header.find('method').text self.assertEqual("METHOD", method_name) self.assertEqual("1", header.find('method-version').text) self.assertEqual("8", header.find('record-id').text) self.assertEqual(AUTH_TOKEN, header.find('auth-session/auth-token').text) self.assertEqual(WC_TOKEN, header.find('auth-session/user-auth-token').text) self.assertEqual("BOO", request.find('info').text)
def test_get_record_id(self): # get record id parses the response okay # need to mock send_request so we can get past getting the auth token with mock.patch.object(HealthVaultConn, '_send_request') as sr: return_xml = u'''<?xml version="1.0" ?> <response> <wc:info xmlns:wc="urn:com.microsoft.wc.methods.response.CreateAuthenticatedSessionToken"> <token>Foo</token> </wc:info> </response>''' return_tree = ET.fromstring(return_xml) sr.return_value = 4, return_xml, return_tree with mock.patch.object(HealthVaultConn, '_build_and_send_request') as basr: xml = u'''<?xml version="1.0" ?> <response> <x:info xmlns:x="urn:com.microsoft.wc.methods.response.GetPersonInfo"> <person-info> <person-id>PERSON-ID</person-id> <name>John Doe</name> <selected-record-id>RECORD-ID</selected-record-id> </person-info> </x:info> </response>''' tree = ET.fromstring(xml) basr.return_value = 18, xml, tree c = HealthVaultConn(app_id="1", app_thumbprint="2", public_key=TEST_PUBLIC_KEY, private_key=TEST_PRIVATE_KEY, wctoken="fakewctoken", server="6", shell_server="7") self.assertEqual("RECORD-ID", c.record_id)
def __init__(self, request, client_address, server): """We need to init a lot because a new one of these gets created for every request. Things we need to keep around we attach to the server object via self.server """ self.server = server # the superclass __init__ does this anyway if not hasattr(self.server, 'conn'): wctoken = None if os.path.exists("WCTOKEN"): with open("WCTOKEN", "r") as f: wctoken = f.read() if not wctoken: os.remove("WCTOKEN") record_id = None if os.path.exists("RECORD_ID"): with open("RECORD_ID", "r") as f: record_id = f.read() try: self.server.conn = HealthVaultConn(wctoken=wctoken, app_id=APP_ID, app_thumbprint=THUMBPRINT, public_key=APP_PUBLIC_KEY, private_key=APP_PRIVATE_KEY, record_id=record_id) except HealthVaultException as e: print e # Leave it un-authorized # set up un-authorized conn self.server.conn = HealthVaultConn(app_id=APP_ID, app_thumbprint=THUMBPRINT, public_key=APP_PUBLIC_KEY, private_key=APP_PRIVATE_KEY, record_id=record_id) else: if self.server.conn.record_id: with open("RECORD_ID", "w") as f: f.write(self.server.conn.record_id) # And this is a stupid old-style class, sigh # AND THE __init__ PROCESSES THE REQUEST! ARGGG BaseHTTPServer.BaseHTTPRequestHandler.__init__(self, request, client_address, server)
def test_is_authorized(self): with mock.patch.object(HealthVaultConn, '_get_auth_token'): c = HealthVaultConn(app_id="1", app_thumbprint="2", public_key=TEST_PUBLIC_KEY, private_key=TEST_PRIVATE_KEY, wctoken=None, server="6", shell_server="7") self.assertFalse(c.is_authorized()) c.authorized = True self.assertTrue(c.is_authorized())
def mvaultentry(request): target = request.GET['target'] wctoken = "" if target == "AppAuthSuccess": wctoken = request.GET['wctoken'] else: return HttpResponse("cannot get wctoken") hvconn = HealthVaultConn(wctoken) demo = hvconn.getBasicDemographicInfo() template_values = {'basicdemographic':demo} return render_to_response('hvdata.html',template_values)
def get_dummy_health_vault_conn(self): """Construct a HealthVaultConn, mocking any network traffic, and return it""" with mock.patch.object(HealthVaultConn, '_get_auth_token'): with mock.patch.object(HealthVaultConn, '_get_record_id') as gri: gri.return_value = 8 c = HealthVaultConn(app_id="1", app_thumbprint="2", public_key=TEST_PUBLIC_KEY, private_key=TEST_PRIVATE_KEY, wctoken="5", server="6", shell_server="7") return c
def test_get_auth_token(self): # At least test that when we connect, get_auth_token is called and calls SendRequest, # and parses the response okay and returns it with mock.patch.object(HealthVaultConn, '_send_request') as sr: return_xml = u'<?xml version="1.0" ?><response><wc:info xmlns:wc="urn:com.microsoft.wc.methods.response.CreateAuthenticatedSessionToken"><token>Foo</token></wc:info></response>' return_tree = ET.fromstring(return_xml) sr.return_value = 4, return_xml, return_tree with mock.patch.object(HealthVaultConn, '_get_record_id') as gri: gri.return_value = 1 c = HealthVaultConn(app_id="1", app_thumbprint="2", public_key=TEST_PUBLIC_KEY, private_key=TEST_PRIVATE_KEY, wctoken=None, server="6", shell_server="7") # send request should have been called just once, we didn't provide a wctoken self.assertEqual(1, sr.call_count) # and we got the auth token from the response self.assertEqual("Foo", c.auth_token)
def test_authorization_url(self): with mock.patch.object(HealthVaultConn, '_get_auth_token'): c = HealthVaultConn(app_id="123", app_thumbprint="2", public_key=TEST_PUBLIC_KEY, private_key=TEST_PRIVATE_KEY, wctoken=None, server="6", shell_server="shell.server") url = c.authorization_url("http://ourown.server.com/with/some/parts/") self.assertIsNotNone( re. compile('https://shell\.server/redirect\.aspx\?[{0}&{0}]'.format( '(target=APPAUTH)|(targetqs={0}%26{0})'.format( '(redirect%3Dhttp%253A%252F%252Fourown\.server\.com%252Fwith%252Fsome%252Fparts%252F)|' '(appid%3D123)'))).match(url)) # callback URL is optional url = c.authorization_url() self.assertIsNotNone( re.compile( 'https://shell\.server/redirect\.aspx\?[{0}&{0}]'.format( '(targetqs=appid%3D123)|(target=APPAUTH)')).match(url)) # Can include record_id url = c.authorization_url(record_id="FooBar") self.assertIsNotNone( re.compile( 'https://shell\.server/redirect\.aspx\?[{0}&{0}]'.format( '(targetqs={0}%26{0})|(target=APPAUTH)'.format( '(extrecordid%3DFooBar)|(appid%3D123)'))).match(url)) # Or both url = c.authorization_url("http://ourown.server.com/with/some/parts/", record_id="FooBar") self.assertIsNotNone( re. compile('https://shell\.server/redirect\.aspx\?[{0}&{0}]'.format( '(targetqs={0}%26{0}%26{0})|(target=APPAUTH)'.format( '(redirect%3Dhttp%253A%252F%252Fourown\.server\.com%252Fwith%252Fsome%252Fparts%252F)|' '(extrecordid%3DFooBar)|(appid%3D123)'))).match(url))
def test_very_simple(self): # construct a conn, mocking all the real work with mock.patch.object(HealthVaultConn, '_get_auth_token') as gat: with mock.patch.object(HealthVaultConn, '_get_record_id') as gri: gri.return_value = 8 c = HealthVaultConn(app_id="1", app_thumbprint="2", public_key=TEST_PUBLIC_KEY, private_key=TEST_PRIVATE_KEY, wctoken="5", server="6", shell_server="7") self.assertEqual("1", c.app_id) self.assertEqual("2", c.app_thumbprint) self.assertEqual(TEST_PUBLIC_KEY, c.public_key) self.assertEqual(TEST_PRIVATE_KEY, c.private_key) self.assertEqual("5", c.wctoken) self.assertEqual("6", c.server) self.assertEqual("7", c.shell_server) self.assertEqual(8, c.record_id) # We passed in a wctoken, make sure the methods got called that set up things with HealthVault gat.assert_any_call() gri.assert_any_call()
def create_connection(wctoken=None, record_id=None, **kwargs): """Shortcut to create a HealthVaultConn instance. HealthVault configuration parameters can be passed in but default to those defined in the project settings. The `wctoken` authenticates this connection to retrieve data for a specific user. If the `record_id` of the corresponding user is known, it can be passed in to save a network call to look up the `record_id`. The `sharedsec` and `auth_token` generated by a HealthVaultConn are cached to be used again in future connections. If HealthVaultConn raises a ValueError, this is caught and an :py:exc:`django.core.exceptions.ImproperlyConfigured` exception is thrown in its place. Other exceptions thrown by HealthVaultConn are propagated. :raises: :py:exc:`django.core.exceptions.ImproperlyConfigured` if settings are unspecified, null/blank, or incorrect. """ global sharedsec, auth_token # Default configuration parameters from the settings. config = { 'app_id': get_setting('HEALTHVAULT_APP_ID'), 'app_thumbprint': get_setting('HEALTHVAULT_THUMBPRINT'), 'public_key': get_setting('HEALTHVAULT_PUBLIC_KEY'), 'private_key': get_setting('HEALTHVAULT_PRIVATE_KEY'), 'server': get_setting('HEALTHVAULT_SERVER'), 'shell_server': get_setting('HEALTHVAULT_SHELL_SERVER'), } config.update(kwargs) # Require that configuration parameters be non-null. for key, value in config.items(): if not value: msg = '{0} cannot be null, and must be explicitly ' \ 'specified or set in your Django settings.'.format(key) raise ImproperlyConfigured(msg) # Since sharedsec and auth_token go together, reset them if both aren't # present. if sharedsec and auth_token: config['sharedsec'] = sharedsec config['auth_token'] = auth_token else: shared_secret = None auth_token = None try: conn = HealthVaultConn(wctoken=wctoken, record_id=record_id, **config) except ValueError as e: logger.error(e) msg = e.args[0] if e.args else None raise ImproperlyConfigured( 'Public and private keys should be long values: {0}'.format(msg)) except HealthVaultException as e: # We must reset sharedsec and auth_token in the case that the ones we # have are expired or invalid and can't be reused. sharedsec = None auth_token = None logger.error(e) raise e # Save the sharedsec and auth_token for future use. sharedsec = conn.sharedsec auth_token = conn.auth_token return conn