def get_soap_header(self): """ Generate the SOAP authentication header for the related service. This header contains all the necessary authentication details. Returns: (str): A string representation of the XML content of the SOAP header """ # According to the SONOS SMAPI, this header must be sent with all # SOAP requests. Building this is an expensive operation (though # occasionally necessary), so f we have a cached value, return it if self._cached_soap_header is not None: return self._cached_soap_header music_service = self.music_service credentials_header = XML.Element( "credentials", {'xmlns': "http://www.sonos.com/Services/1.1"}) device_id = XML.SubElement(credentials_header, 'deviceId') device_id.text = self._device_id device_provider = XML.SubElement(credentials_header, 'deviceProvider') device_provider.text = 'Sonos' if music_service.account.oa_device_id: # OAuth account credentials are present. We must use them to # authenticate. login_token = XML.Element('loginToken') token = XML.SubElement(login_token, 'token') token.text = music_service.account.oa_device_id key = XML.SubElement(login_token, 'key') key.text = music_service.account.key household_id = XML.SubElement(login_token, 'householdId') household_id.text = self._device.household_id credentials_header.append(login_token) # otherwise, perhaps use DeviceLink or UserId auth elif music_service.auth_type in ['DeviceLink', 'UserId']: # We need a session ID from Sonos session_id = self._device.musicServices.GetSessionId([ ('ServiceId', music_service.service_id), ('Username', music_service.account.username) ])['SessionId'] session_elt = XML.Element('sessionId') session_elt.text = session_id credentials_header.append(session_elt) # Anonymous auth. No need for anything further. self._cached_soap_header = XML.tostring(credentials_header) return self._cached_soap_header