0

I have the following SOAP Request, that I should be able to handle:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
    <LogoutNotification xmlns="urn:mace:shibboleth:2.0:sp:notify" type="global">
      <SessionID>
        _d5628602323819f716fcee04103ad5ef
      </SessionID>
    </LogoutNotification>
  </s:Body>
</s:Envelope>

SessionID is simply the RPC parameter. That's easy to handle.

But how can I model the type attribute in spyne? type is either "global" or "local".

I currently have the following (and disabled validation to be able to simply ignore the attribute):

class LogoutNotificationService(Service):
    @rpc(MandatoryUnicode, _returns=OKType,
         _in_variable_names={'sessionid': 'SessionID'},
         _out_variable_name='OK',
         )
    def LogoutNotification(ctx, sessionid):
        pass # handle the request

For sake of completeness here are the used models:

class OKType(ComplexModel):
    pass


class MandatoryUnicode(Unicode):
    class Attributes(Unicode.Attributes):
        nullable = False
        min_occurs = 1

The schema is online. But there is no official WSDL for this containing the attribute.

Enno Gröper
  • 4,391
  • 1
  • 27
  • 33

1 Answers1

1

The key to this is using the bare body style. Then you can (and need to) model the complete input and output message.

My working code looks like this:

class OKType(ComplexModel):
    pass


class MandatoryUnicode(Unicode):
    class Attributes(Unicode.Attributes):
        nullable = False
        min_occurs = 1


class LogoutRequest(ComplexModel):
    __namespace__ = 'urn:mace:shibboleth:2.0:sp:notify'
    SessionID = MandatoryUnicode
    type = XmlAttribute(Enum("global", "local", type_name="LogoutNotificationType"))


class LogoutResponse(ComplexModel):
    __namespace__ = 'urn:mace:shibboleth:2.0:sp:notify'
    OK = OKType


class LogoutNotificationService(Service):
    @rpc(LogoutRequest, _returns=LogoutResponse, _body_style='bare')
    def LogoutNotification(ctx, req):
        # do stuff, raise Fault on error
        # sessionid is available as req.SessionID
        return LogoutResponse

The (not really related question) about not wrapping response contains good examples and showed me how to solve this problem.

Enno Gröper
  • 4,391
  • 1
  • 27
  • 33