Example #1
0
    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