Skip to content

Commit

Permalink
Support loading WSDL from secured server
Browse files Browse the repository at this point in the history
  • Loading branch information
ombre42 committed Oct 5, 2014
1 parent 784c0bf commit 6e3e0b0
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 15 deletions.
11 changes: 10 additions & 1 deletion src/SudsLibrary/clientmanagement.py
Expand Up @@ -23,7 +23,8 @@

class _ClientManagementKeywords(object):

def create_soap_client(self, url_or_path, alias=None, autoblend=False, timeout='90 seconds'):
def create_soap_client(self, url_or_path, alias=None, autoblend=False, timeout='90 seconds', username=None,
password=None, auth_type='STANDARD'):
"""Loads a WSDL from the given URL/path and creates a Suds SOAP client.
Returns the index of this client instance which can be used later to
Expand All @@ -33,6 +34,10 @@ def create_soap_client(self, url_or_path, alias=None, autoblend=False, timeout='
for switching between clients (just as index can be used). See `Switch
Soap Client` for more details.
`username` and `password` are needed if the WSDL is on a server
requiring basic authentication. `auth_type` selects the authentication
scheme to use. See `Set Http Authentication` for more information.
Autoblend ensures that the schema(s) defined within the WSDL import
each other.
Expand All @@ -46,6 +51,10 @@ def create_soap_client(self, url_or_path, alias=None, autoblend=False, timeout='
url = self._get_url(url_or_path)
autoblend = to_bool(autoblend)
kwargs = {'autoblend': autoblend}
if username:
password = password if password is not None else ""
transport = self._get_transport(auth_type, username, password)
kwargs['transport'] = transport
imports = self._imports
if imports:
self._log_imports()
Expand Down
29 changes: 17 additions & 12 deletions src/SudsLibrary/options.py
Expand Up @@ -119,19 +119,11 @@ def set_http_authentication(self, username, password, type='STANDARD'):
will only send credentials to the server upon request (HTTP/1.0 401
Authorization Required) by the server only. Type ALWAYS_SEND will
cause an Authorization header to be sent in every request. Type NTLM
requires the python-ntlm package to be installed, which is not
packaged with Suds or SudsLibrary.
is a Microsoft proprietary authentication scheme that requires the
python-ntlm package to be installed, which is not packaged with Suds
or SudsLibrary.
"""
classes = {
'STANDARD': HttpAuthenticated,
'ALWAYS_SEND': AlwaysSendTransport,
'NTLM': WindowsHttpAuthenticated
}
try:
_class = classes[type.upper()]
except KeyError:
raise ValueError("'%s' is not a supported type." % type)
transport = _class(username=username, password=password)
transport = self._get_transport(type, username=username, password=password)
self._client().set_options(transport=transport)

def set_location(self, url, service=None, names=None):
Expand Down Expand Up @@ -236,3 +228,16 @@ def _set_external_option(self, name, value):
old_value = self._external_options[self._client()].get(name, None)
self._external_options[self._client()][name] = value
return old_value

def _get_transport(self, auth_type, username, password):
classes = {
'STANDARD': HttpAuthenticated,
'ALWAYS_SEND': AlwaysSendTransport,
'NTLM': WindowsHttpAuthenticated
}
try:
_class = classes[auth_type.upper().strip()]
except KeyError:
raise ValueError("'%s' is not a supported authentication type." % auth_type)
transport = _class(username=username, password=password)
return transport
20 changes: 18 additions & 2 deletions test/acceptance/basicauth.robot
@@ -1,5 +1,5 @@
*** Settings ***
Resource resource.txt
Resource resource.txt

*** Test Cases ***
Http Authentication
Expand All @@ -15,4 +15,20 @@ Http Authentication
${request} Get Sent Request
# auth not needed, but should have been sent anyways
Should Be Equal As Strings ${request.headers['Authorization']} Basic Ym9iOmZvbw==
Run Keyword And Expect Error ValueError: 'bad' is not a supported type. Set Http Authentication bob foo bad

Secured WSDL
Run Keyword And Expect Error *401* Create Soap Client ${SECURE TEST WSDL URL} # sanity check
Create Soap Client ${SECURE TEST WSDL URL} username=beth password=beth
${answer} Call Soap Method theAnswer
Should Be Equal ${answer} ${42}

Unsecure WSDL With Secured Import
[Documentation] To test that the transport is used on imports, use a WSDL that does not require authentication that imports a document that does require authentication.
Create Soap Client ${WSDL DIR}/TestServices_secured_import.wsdl username=beth password=beth
${answer} Call Soap Method theAnswer
Should Be Equal ${answer} ${42}

Bad Authentication Type
Run Keyword And Expect Error ValueError: 'bad' is not a supported authentication type. Create Soap Client ${TEST WSDL URL} username=bob password=foo auth_type=bad
Create Soap Client ${TEST WSDL URL}
Run Keyword And Expect Error ValueError: 'bad' is not a supported authentication type. Set Http Authentication bob foo bad
2 changes: 2 additions & 0 deletions test/acceptance/resource.txt
Expand Up @@ -11,3 +11,5 @@ ${CALCULATOR WSDL URL} http://localhost:8080/Calculator/soap11/description
${TEST WSDL URL} http://localhost:8080/TestService/soap11/description
${SECURE TEST WSDL URL} http://localhost:8080/secure/TestService/soap11/description
${SECURE TEST URL} http://localhost:8080/secure/TestService/soap11
${WSDL DIR} http://localhost:8080/wsdls
${SECURE WSDL DIR} http://localhost:8080/secure/wsdls
9 changes: 9 additions & 0 deletions test/resources/wsdls/ImportedType.xsd
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema targetNamespace="http://tempuri.org/schemas" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:complexType name="Person">
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="first-name" type="xsd:string"/>
<xsd:element maxOccurs="1" minOccurs="1" name="last-name" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
76 changes: 76 additions & 0 deletions test/resources/wsdls/TestServices_secured_import.wsdl
@@ -0,0 +1,76 @@
<!-- requires http auth to fetch imported schema -->
<wsdl:definitions name="TestService" targetNamespace="urn:TestService" xmlns:xsd1="http://tempuri.org/schemas" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="urn:TestService" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<wsdl:types>
<xsd:schema targetNamespace="urn:TestService">
<xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
<xsd:import namespace="http://tempuri.org/schemas" schemaLocation="http://localhost:8080/secure/wsdls/ImportedType.xsd"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="complexTypeArgument">
<wsdl:part name="person" type="xsd1:Person"/>
</wsdl:message>
<wsdl:message name="complexTypeArgumentResponse">
<wsdl:part name="result" type="xsd:string"/>
</wsdl:message>
<wsdl:message name="returnComplexType">
<wsdl:part name="first-name" type="xsd:string"/>
<wsdl:part name="last-name" type="xsd:string"/>
</wsdl:message>
<wsdl:message name="returnComplexTypeResponse">
<wsdl:part name="result" type="xsd1:Person"/>
</wsdl:message>
<wsdl:message name="theAnswer"/>
<wsdl:message name="theAnswerResponse">
<wsdl:part name="result" type="xsd:long"/>
</wsdl:message>
<wsdl:portType name="TestServicePortType">
<wsdl:operation name="complexTypeArgument">
<wsdl:input message="tns:complexTypeArgument"/>
<wsdl:output message="tns:complexTypeArgumentResponse"/>
</wsdl:operation>
<wsdl:operation name="returnComplexType">
<wsdl:input message="tns:returnComplexType"/>
<wsdl:output message="tns:returnComplexTypeResponse"/>
</wsdl:operation>
<wsdl:operation name="theAnswer">
<wsdl:input message="tns:theAnswer"/>
<wsdl:output message="tns:theAnswerResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="TestService" type="tns:TestServicePortType">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="complexTypeArgument">
<soap:operation soapAction="http://localhost:8080/TestService/soap11/complexTypeArgument" style="rpc"/>
<wsdl:input>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:TestService" use="encoded"/>
</wsdl:input>
<wsdl:output>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:TestService" use="encoded"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="returnComplexType">
<soap:operation soapAction="http://localhost:8080/TestService/soap11/returnComplexType" style="rpc"/>
<wsdl:input>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:TestService" use="encoded"/>
</wsdl:input>
<wsdl:output>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:TestService" use="encoded"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="theAnswer">
<soap:operation soapAction="http://localhost:8080/TestService/soap11/theAnswer" style="rpc"/>
<wsdl:input>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:TestService" use="encoded"/>
</wsdl:input>
<wsdl:output>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:TestService" use="encoded"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="TestService">
<wsdl:documentation>Ladon generated service definition</wsdl:documentation>
<wsdl:port binding="tns:TestService" name="TestService">
<soap:address location="http://localhost:8080/TestService/soap11"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

0 comments on commit 6e3e0b0

Please sign in to comment.