Add Claims support to web-app-policy-ACL and use of people.asmx to resolve policy users
Code review : https://codereview.appspot.com/12892043/
diff --git a/People.spec.wsdl b/People.spec.wsdl
new file mode 100644
index 0000000..42c5ab2
--- /dev/null
+++ b/People.spec.wsdl
@@ -0,0 +1,195 @@
+<?xml version="1.0" encoding="utf-8"?>
+<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"
+xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
+xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
+xmlns:tns="http://schemas.microsoft.com/sharepoint/soap/"
+xmlns:s="http://www.w3.org/2001/XMLSchema"
+xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
+xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
+targetNamespace="http://schemas.microsoft.com/sharepoint/soap/"
+xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
+ <wsdl:types>
+ <s:schema elementFormDefault="qualified" targetNamespace="http://schemas.microsoft.com/sharepoint/soap/">
+ <s:element name="IsClaimsMode">
+ <s:complexType />
+ </s:element>
+ <s:element name="IsClaimsModeResponse">
+ <s:complexType>
+ <s:sequence>
+ <s:element minOccurs="1" maxOccurs="1" name="IsClaimsModeResult" type="s:boolean" />
+ </s:sequence>
+ </s:complexType>
+ </s:element>
+ <s:element name="ResolvePrincipals">
+ <s:complexType>
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="1" name="principalKeys" type="tns:ArrayOfString" />
+ <s:element minOccurs="1" maxOccurs="1" name="principalType" type="tns:SPPrincipalType" />
+ <s:element minOccurs="1" maxOccurs="1" name="addToUserInfoList" type="s:boolean" />
+ </s:sequence>
+ </s:complexType>
+ </s:element>
+ <s:complexType name="ArrayOfString">
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="unbounded" name="string" nillable="true" type="s:string" />
+ </s:sequence>
+ </s:complexType>
+ <s:simpleType name="SPPrincipalType">
+ <s:list>
+ <s:simpleType>
+ <s:restriction base="s:string">
+ <s:enumeration value="None" />
+ <s:enumeration value="User" />
+ <s:enumeration value="DistributionList" />
+ <s:enumeration value="SecurityGroup" />
+ <s:enumeration value="SharePointGroup" />
+ <s:enumeration value="All" />
+ </s:restriction>
+ </s:simpleType>
+ </s:list>
+ </s:simpleType>
+ <s:element name="ResolvePrincipalsResponse">
+ <s:complexType>
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="1" name="ResolvePrincipalsResult" type="tns:ArrayOfPrincipalInfo" />
+ </s:sequence>
+ </s:complexType>
+ </s:element>
+ <s:complexType name="ArrayOfPrincipalInfo">
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="unbounded" name="PrincipalInfo" type="tns:PrincipalInfo" />
+ </s:sequence>
+ </s:complexType>
+ <s:complexType name="PrincipalInfo">
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="1" name="AccountName" type="s:string" />
+ <s:element minOccurs="1" maxOccurs="1" name="UserInfoID" type="s:int" />
+ <s:element minOccurs="0" maxOccurs="1" name="DisplayName" type="s:string" />
+ <s:element minOccurs="0" maxOccurs="1" name="Email" type="s:string" />
+ <s:element minOccurs="0" maxOccurs="1" name="Department" type="s:string" />
+ <s:element minOccurs="0" maxOccurs="1" name="Title" type="s:string" />
+ <s:element minOccurs="1" maxOccurs="1" name="IsResolved" type="s:boolean" />
+ <s:element minOccurs="0" maxOccurs="1" name="MoreMatches" type="tns:ArrayOfPrincipalInfo" />
+ <s:element minOccurs="1" maxOccurs="1" name="PrincipalType" type="tns:SPPrincipalType" />
+ </s:sequence>
+ </s:complexType>
+ <s:element name="SearchPrincipals">
+ <s:complexType>
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="1" name="searchText" type="s:string" />
+ <s:element minOccurs="1" maxOccurs="1" name="maxResults" type="s:int" />
+ <s:element minOccurs="1" maxOccurs="1" name="principalType" type="tns:SPPrincipalType" />
+ </s:sequence>
+ </s:complexType>
+ </s:element>
+ <s:element name="SearchPrincipalsResponse">
+ <s:complexType>
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="1" name="SearchPrincipalsResult" type="tns:ArrayOfPrincipalInfo" />
+ </s:sequence>
+ </s:complexType>
+ </s:element>
+ </s:schema>
+ </wsdl:types>
+ <wsdl:message name="IsClaimsModeSoapIn">
+ <wsdl:part name="parameters" element="tns:IsClaimsMode" />
+ </wsdl:message>
+ <wsdl:message name="IsClaimsModeSoapOut">
+ <wsdl:part name="parameters" element="tns:IsClaimsModeResponse" />
+ </wsdl:message>
+ <wsdl:message name="ResolvePrincipalsSoapIn">
+ <wsdl:part name="parameters" element="tns:ResolvePrincipals" />
+ </wsdl:message>
+ <wsdl:message name="ResolvePrincipalsSoapOut">
+ <wsdl:part name="parameters" element="tns:ResolvePrincipalsResponse" />
+ </wsdl:message>
+ <wsdl:message name="SearchPrincipalsSoapIn">
+ <wsdl:part name="parameters" element="tns:SearchPrincipals" />
+ </wsdl:message>
+ <wsdl:message name="SearchPrincipalsSoapOut">
+ <wsdl:part name="parameters" element="tns:SearchPrincipalsResponse" />
+ </wsdl:message>
+ <wsdl:portType name="PeopleSoap">
+ <wsdl:operation name="IsClaimsMode">
+ <wsdl:input message="tns:IsClaimsModeSoapIn" />
+ <wsdl:output message="tns:IsClaimsModeSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="ResolvePrincipals">
+ <wsdl:input message="tns:ResolvePrincipalsSoapIn" />
+ <wsdl:output message="tns:ResolvePrincipalsSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="SearchPrincipals">
+ <wsdl:input message="tns:SearchPrincipalsSoapIn" />
+ <wsdl:output message="tns:SearchPrincipalsSoapOut" />
+ </wsdl:operation>
+ </wsdl:portType>
+ <wsdl:binding name="PeopleSoap" type="tns:PeopleSoap">
+ <soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
+ <wsdl:operation name="IsClaimsMode">
+ <soap:operation soapAction="http://schemas.microsoft.com/sharepoint/soap/IsClaimsMode" style="document" />
+ <wsdl:input>
+ <soap:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="ResolvePrincipals">
+ <soap:operation soapAction="http://schemas.microsoft.com/sharepoint/soap/ResolvePrincipals" style="document" />
+ <wsdl:input>
+ <soap:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="SearchPrincipals">
+ <soap:operation soapAction="http://schemas.microsoft.com/sharepoint/soap/SearchPrincipals" style="document" />
+ <wsdl:input>
+ <soap:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+ </wsdl:binding>
+ <wsdl:binding name="PeopleSoap12" type="tns:PeopleSoap">
+ <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
+ <wsdl:operation name="IsClaimsMode">
+ <soap12:operation soapAction="http://schemas.microsoft.com/sharepoint/soap/IsClaimsMode" style="document" />
+ <wsdl:input>
+ <soap12:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap12:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="ResolvePrincipals">
+ <soap12:operation soapAction="http://schemas.microsoft.com/sharepoint/soap/ResolvePrincipals" style="document" />
+ <wsdl:input>
+ <soap12:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap12:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="SearchPrincipals">
+ <soap12:operation soapAction="http://schemas.microsoft.com/sharepoint/soap/SearchPrincipals" style="document" />
+ <wsdl:input>
+ <soap12:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap12:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+ </wsdl:binding>
+ <wsdl:service name="People">
+ <wsdl:port name="PeopleSoap" binding="tns:PeopleSoap">
+ <soap:address location="http://entpoint05/_vti_bin/People.asmx" />
+ </wsdl:port>
+ <wsdl:port name="PeopleSoap12" binding="tns:PeopleSoap12">
+ <soap12:address location="http://entpoint05/_vti_bin/People.asmx" />
+ </wsdl:port>
+ </wsdl:service>
+</wsdl:definitions>
\ No newline at end of file
diff --git a/People.wsdl b/People.wsdl
new file mode 100644
index 0000000..48bb5f3
--- /dev/null
+++ b/People.wsdl
@@ -0,0 +1,195 @@
+<?xml version="1.0" encoding="utf-8"?>
+<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"
+xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
+xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
+xmlns:tns="http://schemas.microsoft.com/sharepoint/soap/"
+xmlns:s="http://www.w3.org/2001/XMLSchema"
+xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
+xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
+targetNamespace="http://schemas.microsoft.com/sharepoint/soap/"
+xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
+ <wsdl:types>
+ <s:schema elementFormDefault="qualified" targetNamespace="http://schemas.microsoft.com/sharepoint/soap/">
+ <s:element name="IsClaimsMode">
+ <s:complexType />
+ </s:element>
+ <s:element name="IsClaimsModeResponse">
+ <s:complexType>
+ <s:sequence>
+ <s:element minOccurs="1" maxOccurs="1" name="IsClaimsModeResult" type="s:boolean" />
+ </s:sequence>
+ </s:complexType>
+ </s:element>
+ <s:element name="ResolvePrincipals">
+ <s:complexType>
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="1" name="principalKeys" type="tns:ArrayOfString" />
+ <s:element minOccurs="1" maxOccurs="1" name="principalType" type="tns:SPPrincipalType" />
+ <s:element minOccurs="1" maxOccurs="1" name="addToUserInfoList" type="s:boolean" />
+ </s:sequence>
+ </s:complexType>
+ </s:element>
+ <s:complexType name="ArrayOfString">
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="unbounded" name="string" nillable="true" type="s:string" />
+ </s:sequence>
+ </s:complexType>
+ <s:simpleType name="SPPrincipalType">
+ <!--s:list>
+ <s:simpleType-->
+ <s:restriction base="s:string">
+ <s:enumeration value="None" />
+ <s:enumeration value="User" />
+ <s:enumeration value="DistributionList" />
+ <s:enumeration value="SecurityGroup" />
+ <s:enumeration value="SharePointGroup" />
+ <s:enumeration value="All" />
+ </s:restriction>
+ <!--/s:simpleType>
+ </s:list-->
+ </s:simpleType>
+ <s:element name="ResolvePrincipalsResponse">
+ <s:complexType>
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="1" name="ResolvePrincipalsResult" type="tns:ArrayOfPrincipalInfo" />
+ </s:sequence>
+ </s:complexType>
+ </s:element>
+ <s:complexType name="ArrayOfPrincipalInfo">
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="unbounded" name="PrincipalInfo" type="tns:PrincipalInfo" />
+ </s:sequence>
+ </s:complexType>
+ <s:complexType name="PrincipalInfo">
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="1" name="AccountName" type="s:string" />
+ <s:element minOccurs="1" maxOccurs="1" name="UserInfoID" type="s:int" />
+ <s:element minOccurs="0" maxOccurs="1" name="DisplayName" type="s:string" />
+ <s:element minOccurs="0" maxOccurs="1" name="Email" type="s:string" />
+ <s:element minOccurs="0" maxOccurs="1" name="Department" type="s:string" />
+ <s:element minOccurs="0" maxOccurs="1" name="Title" type="s:string" />
+ <s:element minOccurs="1" maxOccurs="1" name="IsResolved" type="s:boolean" />
+ <s:element minOccurs="0" maxOccurs="1" name="MoreMatches" type="tns:ArrayOfPrincipalInfo" />
+ <s:element minOccurs="1" maxOccurs="1" name="PrincipalType" type="tns:SPPrincipalType" />
+ </s:sequence>
+ </s:complexType>
+ <s:element name="SearchPrincipals">
+ <s:complexType>
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="1" name="searchText" type="s:string" />
+ <s:element minOccurs="1" maxOccurs="1" name="maxResults" type="s:int" />
+ <s:element minOccurs="1" maxOccurs="1" name="principalType" type="tns:SPPrincipalType" />
+ </s:sequence>
+ </s:complexType>
+ </s:element>
+ <s:element name="SearchPrincipalsResponse">
+ <s:complexType>
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="1" name="SearchPrincipalsResult" type="tns:ArrayOfPrincipalInfo" />
+ </s:sequence>
+ </s:complexType>
+ </s:element>
+ </s:schema>
+ </wsdl:types>
+ <wsdl:message name="IsClaimsModeSoapIn">
+ <wsdl:part name="parameters" element="tns:IsClaimsMode" />
+ </wsdl:message>
+ <wsdl:message name="IsClaimsModeSoapOut">
+ <wsdl:part name="parameters" element="tns:IsClaimsModeResponse" />
+ </wsdl:message>
+ <wsdl:message name="ResolvePrincipalsSoapIn">
+ <wsdl:part name="parameters" element="tns:ResolvePrincipals" />
+ </wsdl:message>
+ <wsdl:message name="ResolvePrincipalsSoapOut">
+ <wsdl:part name="parameters" element="tns:ResolvePrincipalsResponse" />
+ </wsdl:message>
+ <wsdl:message name="SearchPrincipalsSoapIn">
+ <wsdl:part name="parameters" element="tns:SearchPrincipals" />
+ </wsdl:message>
+ <wsdl:message name="SearchPrincipalsSoapOut">
+ <wsdl:part name="parameters" element="tns:SearchPrincipalsResponse" />
+ </wsdl:message>
+ <wsdl:portType name="PeopleSoap">
+ <wsdl:operation name="IsClaimsMode">
+ <wsdl:input message="tns:IsClaimsModeSoapIn" />
+ <wsdl:output message="tns:IsClaimsModeSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="ResolvePrincipals">
+ <wsdl:input message="tns:ResolvePrincipalsSoapIn" />
+ <wsdl:output message="tns:ResolvePrincipalsSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="SearchPrincipals">
+ <wsdl:input message="tns:SearchPrincipalsSoapIn" />
+ <wsdl:output message="tns:SearchPrincipalsSoapOut" />
+ </wsdl:operation>
+ </wsdl:portType>
+ <wsdl:binding name="PeopleSoap" type="tns:PeopleSoap">
+ <soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
+ <wsdl:operation name="IsClaimsMode">
+ <soap:operation soapAction="http://schemas.microsoft.com/sharepoint/soap/IsClaimsMode" style="document" />
+ <wsdl:input>
+ <soap:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="ResolvePrincipals">
+ <soap:operation soapAction="http://schemas.microsoft.com/sharepoint/soap/ResolvePrincipals" style="document" />
+ <wsdl:input>
+ <soap:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="SearchPrincipals">
+ <soap:operation soapAction="http://schemas.microsoft.com/sharepoint/soap/SearchPrincipals" style="document" />
+ <wsdl:input>
+ <soap:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+ </wsdl:binding>
+ <wsdl:binding name="PeopleSoap12" type="tns:PeopleSoap">
+ <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
+ <wsdl:operation name="IsClaimsMode">
+ <soap12:operation soapAction="http://schemas.microsoft.com/sharepoint/soap/IsClaimsMode" style="document" />
+ <wsdl:input>
+ <soap12:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap12:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="ResolvePrincipals">
+ <soap12:operation soapAction="http://schemas.microsoft.com/sharepoint/soap/ResolvePrincipals" style="document" />
+ <wsdl:input>
+ <soap12:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap12:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="SearchPrincipals">
+ <soap12:operation soapAction="http://schemas.microsoft.com/sharepoint/soap/SearchPrincipals" style="document" />
+ <wsdl:input>
+ <soap12:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap12:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+ </wsdl:binding>
+ <wsdl:service name="People">
+ <wsdl:port name="PeopleSoap" binding="tns:PeopleSoap">
+ <soap:address location="http://entpoint05/_vti_bin/People.asmx" />
+ </wsdl:port>
+ <wsdl:port name="PeopleSoap12" binding="tns:PeopleSoap12">
+ <soap12:address location="http://entpoint05/_vti_bin/People.asmx" />
+ </wsdl:port>
+ </wsdl:service>
+</wsdl:definitions>
\ No newline at end of file
diff --git a/build.xml b/build.xml
index f8281cb..732c00a 100644
--- a/build.xml
+++ b/build.xml
@@ -165,12 +165,25 @@
<arg value="Authentication.wsdl"/>
<arg value="Authentication.wsdl"/>
</exec>
+ <exec executable="wsimport">
+ <arg value="-s"/>
+ <arg value="${generate.dir}"/>
+ <arg value="-d"/>
+ <arg value="${build-generate.dir}"/>
+ <arg value="-p"/>
+ <arg value="com.microsoft.schemas.sharepoint.soap.people"/>
+ <arg value="-wsdllocation"/>
+ <arg value="People.wsdl"/>
+ <arg value="People.wsdl"/>
+ </exec>
<copy file="SiteData.wsdl"
todir="${build-generate.dir}/com/microsoft/schemas/sharepoint/soap/"/>
<copy file="UserGroup.wsdl"
todir="${build-generate.dir}/com/microsoft/schemas/sharepoint/soap/directory/"/>
<copy file="Authentication.wsdl"
- todir="${build-generate.dir}/com/microsoft/schemas/sharepoint/soap/authentication"/>
+ todir="${build-generate.dir}/com/microsoft/schemas/sharepoint/soap/authentication/"/>
+ <copy file="People.wsdl"
+ todir="${build-generate.dir}/com/microsoft/schemas/sharepoint/soap/people/"/>
<copy file="UserProfileService.wsdl"
todir="${build-generate.dir}/com/microsoft/webservices/sharepointportalserver/userprofileservice/"/>
<copy file="UserProfileChangeService.wsdl"
diff --git a/src/com/google/enterprise/adaptor/sharepoint/FormsAuthenticationHandler.java b/src/com/google/enterprise/adaptor/sharepoint/FormsAuthenticationHandler.java
index 6ab0290..615e8a2 100644
--- a/src/com/google/enterprise/adaptor/sharepoint/FormsAuthenticationHandler.java
+++ b/src/com/google/enterprise/adaptor/sharepoint/FormsAuthenticationHandler.java
@@ -19,7 +19,6 @@
import com.microsoft.schemas.sharepoint.soap.authentication.AuthenticationSoap;
import com.microsoft.schemas.sharepoint.soap.authentication.LoginErrorCode;
import com.microsoft.schemas.sharepoint.soap.authentication.LoginResult;
-
import java.io.IOException;
import java.util.Collections;
import java.util.List;
diff --git a/src/com/google/enterprise/adaptor/sharepoint/SharePointAdaptor.java b/src/com/google/enterprise/adaptor/sharepoint/SharePointAdaptor.java
index 7b90ac5..c2202e3 100644
--- a/src/com/google/enterprise/adaptor/sharepoint/SharePointAdaptor.java
+++ b/src/com/google/enterprise/adaptor/sharepoint/SharePointAdaptor.java
@@ -72,6 +72,11 @@
import com.microsoft.schemas.sharepoint.soap.directory.GetUserCollectionFromSiteResponse.GetUserCollectionFromSiteResult;
import com.microsoft.schemas.sharepoint.soap.directory.User;
import com.microsoft.schemas.sharepoint.soap.directory.UserGroupSoap;
+import com.microsoft.schemas.sharepoint.soap.people.ArrayOfPrincipalInfo;
+import com.microsoft.schemas.sharepoint.soap.people.ArrayOfString;
+import com.microsoft.schemas.sharepoint.soap.people.PeopleSoap;
+import com.microsoft.schemas.sharepoint.soap.people.PrincipalInfo;
+import com.microsoft.schemas.sharepoint.soap.people.SPPrincipalType;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
@@ -511,14 +516,17 @@
String endpointUserGroup = site + "/_vti_bin/UserGroup.asmx";
UserGroupSoap userGroupSoap = soapFactory.newUserGroup(endpointUserGroup);
+ String endpointPeople= site + "/_vti_bin/People.asmx";
+ PeopleSoap peopleSoap = soapFactory.newPeople(endpointPeople);
// JAX-WS RT 2.1.4 doesn't handle headers correctly and always assumes the
// list contains precisely one entry, so we work around it here.
if (authenticationHandler.isFormsAuthentication()) {
addFormsAuthenticationCookies((BindingProvider) siteDataSoap);
- addFormsAuthenticationCookies((BindingProvider) userGroupSoap);
+ addFormsAuthenticationCookies((BindingProvider) userGroupSoap);
+ addFormsAuthenticationCookies((BindingProvider) peopleSoap);
}
siteAdaptor = new SiteAdaptor(site, web, siteDataSoap, userGroupSoap,
- new MemberIdMappingCallable(site),
+ peopleSoap, new MemberIdMappingCallable(site),
new SiteUserIdMappingCallable(site));
siteAdaptors.putIfAbsent(web, siteAdaptor);
siteAdaptor = siteAdaptors.get(web);
@@ -527,6 +535,11 @@
}
private void addFormsAuthenticationCookies(BindingProvider port) {
+ if (authenticationHandler.getAuthenticationCookies().isEmpty()) {
+ // JAX-WS RT 2.1.4 doesn't handle headers correctly and always assumes the
+ // list contains precisely one entry, so we work around it here.
+ return;
+ }
port.getRequestContext().put(MessageContext.HTTP_REQUEST_HEADERS,
Collections.singletonMap("Cookie",
authenticationHandler.getAuthenticationCookies()));
@@ -565,6 +578,7 @@
class SiteAdaptor {
private final SiteDataClient siteDataClient;
private final UserGroupSoap userGroup;
+ private final PeopleSoap people;
private final String siteUrl;
private final String webUrl;
/**
@@ -576,7 +590,7 @@
private final Callable<MemberIdMapping> siteUserIdMappingCallable;
public SiteAdaptor(String site, String web, SiteDataSoap siteDataSoap,
- UserGroupSoap userGroupSoap,
+ UserGroupSoap userGroupSoap, PeopleSoap people,
Callable<MemberIdMapping> memberIdMappingCallable,
Callable<MemberIdMapping> siteUserIdMappingCallable) {
log.entering("SiteAdaptor", "SiteAdaptor",
@@ -593,6 +607,7 @@
this.siteUrl = site;
this.webUrl = web;
this.userGroup = userGroupSoap;
+ this.people = people;
this.siteDataClient = new SiteDataClient(siteDataSoap, xmlValidation);
this.memberIdMappingCallable = memberIdMappingCallable;
this.siteUserIdMappingCallable = siteUserIdMappingCallable;
@@ -725,26 +740,44 @@
List<GroupPrincipal> permitGroups = new ArrayList<GroupPrincipal>();
List<UserPrincipal> denyUsers = new ArrayList<UserPrincipal>();
List<GroupPrincipal> denyGroups = new ArrayList<GroupPrincipal>();
+ List<String> policyUsers = new ArrayList<String>();
for (PolicyUser policyUser : vs.getPolicies().getPolicyUser()) {
- // TODO(ejona): special case NT AUTHORITY\LOCAL SERVICE.
- String loginName = decodeClaim(policyUser.getLoginName(),
- policyUser.getLoginName(), false);
- if (loginName == null) {
+ policyUsers.add(policyUser.getLoginName());
+ }
+ Map<String, PrincipalInfo> resolvedPolicyUsers
+ = resolvePrincipals(policyUsers);
+ for (PolicyUser policyUser : vs.getPolicies().getPolicyUser()) {
+ String loginName = policyUser.getLoginName();
+ PrincipalInfo p = resolvedPolicyUsers.get(loginName);
+ if (p == null || !p.isIsResolved()) {
log.log(Level.WARNING,
- "Unable to decode claim. Skipping policy user {0}",
- policyUser.getLoginName());
+ "Unable to resolve Policy User = {0}", loginName);
+ continue;
}
- log.log(Level.FINER, "Policy User Login Name = {0}", loginName);
+ // TODO(ejona): special case NT AUTHORITY\LOCAL SERVICE.
+ String accountName = decodeClaim(p.getAccountName(), p.getDisplayName(),
+ p.getPrincipalType() == SPPrincipalType.SECURITY_GROUP);
+ if (accountName == null) {
+ log.log(Level.WARNING,
+ "Unable to decode claim. Skipping policy user {0}", loginName);
+ }
+ log.log(Level.FINER, "Policy User accountName = {0}", accountName);
long grant = policyUser.getGrantMask().longValue();
if ((necessaryPermissionMask & grant) == necessaryPermissionMask) {
- permitUsers.add(new UserPrincipal(loginName));
- permitGroups.add(new GroupPrincipal(loginName));
+ if (p.getPrincipalType() == SPPrincipalType.USER) {
+ permitUsers.add(new UserPrincipal(accountName));
+ } else {
+ permitGroups.add(new GroupPrincipal(accountName));
+ }
}
long deny = policyUser.getDenyMask().longValue();
// If at least one necessary bit is masked, then deny user.
if ((necessaryPermissionMask & deny) != 0) {
- denyUsers.add(new UserPrincipal(loginName));
- denyGroups.add(new GroupPrincipal(loginName));
+ if (p.getPrincipalType() == SPPrincipalType.USER) {
+ denyUsers.add(new UserPrincipal(accountName));
+ } else {
+ denyGroups.add(new GroupPrincipal(accountName));
+ }
}
}
response.setAcl(new Acl.Builder()
@@ -1681,14 +1714,14 @@
, boolean isDomainGroup) {
if (!loginName.startsWith(IDENTITY_CLAIMS_PREFIX)
&& !loginName.startsWith(OTHER_CLAIMS_PREFIX)) {
- return isDomainGroup ? name : loginName;
+ return loginName;
}
// AD User
if (loginName.startsWith("i:0#.w|")) {
return loginName.substring(7);
// AD Group
} else if (loginName.startsWith("c:0+.w|")) {
- return name.startsWith("c:0+.w|") ? name.substring(7) : name;
+ return name;
} else if (loginName.equals("c:0(.s|true")) {
return "Everyone";
} else if (loginName.equals("c:0!.s|windows")) {
@@ -1704,6 +1737,29 @@
return null;
}
+ private Map<String,PrincipalInfo> resolvePrincipals(
+ List<String> principalsToResolve) {
+ Map<String, PrincipalInfo> resolved
+ = new HashMap<String, PrincipalInfo>();
+ if (principalsToResolve.isEmpty()) {
+ return resolved;
+ }
+ ArrayOfString aos = new ArrayOfString();
+ aos.getString().addAll(principalsToResolve);
+ ArrayOfPrincipalInfo resolvePrincipals = people.resolvePrincipals(
+ aos, SPPrincipalType.ALL, false);
+ List<PrincipalInfo> principals = resolvePrincipals.getPrincipalInfo();
+ // using loginname from input list principalsToResolve as a key
+ // instead of returned PrincipalInfo.getAccountName() as with claims
+ // authentication PrincipalInfo.getAccountName() is always encoded.
+ // e.g. if login name from Policy is NT Authority\Local Service
+ // returned account name is i:0#.w|NT Authority\Local Service
+ for (int i = 0; i < principalsToResolve.size(); i++) {
+ resolved.put(principalsToResolve.get(i), principals.get(i));
+ }
+ return resolved;
+ }
+
private MemberIdMapping retrieveMemberIdMapping() throws IOException {
log.entering("SiteAdaptor", "retrieveMemberIdMapping");
Site site = siteDataClient.getContentSite();
@@ -1956,6 +2012,8 @@
public UserGroupSoap newUserGroup(String endpoint);
public AuthenticationSoap newAuthentication(String endpoint);
+
+ public PeopleSoap newPeople(String endpoint);
}
@VisibleForTesting
@@ -1963,6 +2021,7 @@
private final Service siteDataService;
private final Service userGroupService;
private final Service authenticationService;
+ private final Service peopleService;
public SoapFactoryImpl() {
this.siteDataService = SiteDataClient.createSiteDataService();
@@ -1972,6 +2031,9 @@
this.authenticationService = Service.create(
AuthenticationSoap.class.getResource("Authentication.wsdl"),
new QName(XMLNS, "Authentication"));
+ this.peopleService = Service.create(
+ PeopleSoap.class.getResource("People.wsdl"),
+ new QName(XMLNS, "People"));
}
@Override
@@ -1995,6 +2057,13 @@
return
authenticationService.getPort(endpointRef, AuthenticationSoap.class);
}
+
+ @Override
+ public PeopleSoap newPeople(String endpoint) {
+ EndpointReference endpointRef = new W3CEndpointReferenceBuilder()
+ .address(endpoint).build();
+ return peopleService.getPort(endpointRef, PeopleSoap.class);
+ }
}
private static class NtlmAuthenticator extends Authenticator {
diff --git a/test/com/google/enterprise/adaptor/sharepoint/SharePointAdaptorTest.java b/test/com/google/enterprise/adaptor/sharepoint/SharePointAdaptorTest.java
index 0bf8c65..663d74d 100644
--- a/test/com/google/enterprise/adaptor/sharepoint/SharePointAdaptorTest.java
+++ b/test/com/google/enterprise/adaptor/sharepoint/SharePointAdaptorTest.java
@@ -31,11 +31,10 @@
import com.google.enterprise.adaptor.UserPrincipal;
import com.google.enterprise.adaptor.sharepoint.SharePointAdaptor.SiteUserIdMappingCallable;
import com.google.enterprise.adaptor.sharepoint.SharePointAdaptor.SoapFactory;
+
import com.microsoft.schemas.sharepoint.soap.authentication.AuthenticationMode;
import com.microsoft.schemas.sharepoint.soap.authentication.AuthenticationSoap;
-import com.microsoft.schemas.sharepoint.soap.authentication.LoginErrorCode;
import com.microsoft.schemas.sharepoint.soap.authentication.LoginResult;
-
import com.microsoft.schemas.sharepoint.soap.ObjectType;
import com.microsoft.schemas.sharepoint.soap.SPContentDatabase;
import com.microsoft.schemas.sharepoint.soap.SiteDataSoap;
@@ -75,6 +74,11 @@
import com.microsoft.schemas.sharepoint.soap.directory.User;
import com.microsoft.schemas.sharepoint.soap.directory.UserGroupSoap;
import com.microsoft.schemas.sharepoint.soap.directory.Users;
+import com.microsoft.schemas.sharepoint.soap.people.ArrayOfPrincipalInfo;
+import com.microsoft.schemas.sharepoint.soap.people.ArrayOfString;
+import com.microsoft.schemas.sharepoint.soap.people.PeopleSoap;
+import com.microsoft.schemas.sharepoint.soap.people.PrincipalInfo;
+import com.microsoft.schemas.sharepoint.soap.people.SPPrincipalType;
import org.junit.*;
import org.junit.rules.ExpectedException;
@@ -363,11 +367,18 @@
@Test
public void testGetDocContentVirtualServer() throws Exception {
+ MockPeopleSoap mockPeople = new MockPeopleSoap();
+ mockPeople.addToResult("NT AUTHORITY\\LOCAL SERVICE",
+ "NT AUTHORITY\\LOCAL SERVICE", SPPrincipalType.USER);
+ mockPeople.addToResult("GDC-PSL\\spuser1", "spuser1", SPPrincipalType.USER);
+ mockPeople.addToResult("GDC-PSL\\Administrator", "dministrator",
+ SPPrincipalType.USER);
SoapFactory siteDataFactory = MockSoapFactory.blank()
.endpoint(AUTH_ENDPOINT, new MockAuthenticationSoap())
.endpoint(VS_ENDPOINT, MockSiteData.blank()
.register(VS_CONTENT_EXCHANGE)
- .register(CD_CONTENT_EXCHANGE));
+ .register(CD_CONTENT_EXCHANGE))
+ .endpoint("http://localhost:1/_vti_bin/People.asmx", mockPeople);
adaptor = new SharePointAdaptor(siteDataFactory,
new UnsupportedHttpClient(), executorFactory);
@@ -392,7 +403,58 @@
assertEquals(new Acl.Builder()
.setEverythingCaseInsensitive()
.setInheritanceType(Acl.InheritanceType.PARENT_OVERRIDES)
- .setPermitUsers(users(permit)).setPermitGroups(groups(permit)).build(),
+ .setPermitUsers(users(permit)).build(), response.getAcl());
+ assertNull(response.getDisplayUrl());
+ }
+
+ @Test
+ public void testPolicyAclsWithClaims() throws Exception {
+ String claimsPolicyUsers = "<PolicyUser "
+ + "LoginName=\"i:0#.w|GSA-CONNECTORS\\Administrator\" "
+ + "BinaryIdentifier=\"i:0).w|s-1-5-21-3993744865-352142399"
+ + "7-1479072767-500\" Sid=\"\" BinaryIdentifierType=\"UserKey\" "
+ + "GrantMask=\"9223372036854775807\" DenyMask=\"0\" />"
+ + "<PolicyUser "
+ + "LoginName=\"c:0+.w|s-1-5-21-3993744865-3521423997-1479072767-513\" "
+ + "BinaryIdentifier=\"c:0+.w|s-1-5-21-3993744865-3521423997"
+ + "-1479072767-513\" Sid=\"\" BinaryIdentifierType=\"UserKey\" "
+ + "GrantMask=\"4611686224789442657\" "
+ + "DenyMask=\"0\" /></Policies>";
+ MockPeopleSoap mockPeople = new MockPeopleSoap();
+ mockPeople.addToResult("i:0#.w|GSA-CONNECTORS\\Administrator",
+ "Administrator", SPPrincipalType.USER);
+ mockPeople.addToResult(
+ "c:0+.w|s-1-5-21-3993744865-3521423997-1479072767-513",
+ "GSA-CONNECTORS\\domain users", SPPrincipalType.SECURITY_GROUP);
+ mockPeople.addToResult("NT AUTHORITY\\LOCAL SERVICE",
+ "NT AUTHORITY\\LOCAL SERVICE", SPPrincipalType.USER);
+ mockPeople.addToResult("GDC-PSL\\spuser1", "spuser1", SPPrincipalType.USER);
+ mockPeople.addToResult("GDC-PSL\\Administrator", "dministrator",
+ SPPrincipalType.USER);
+
+ SoapFactory siteDataFactory = MockSoapFactory.blank()
+ .endpoint(AUTH_ENDPOINT, new MockAuthenticationSoap())
+ .endpoint(VS_ENDPOINT, MockSiteData.blank()
+ .register(VS_CONTENT_EXCHANGE
+ .replaceInContent("</Policies>", claimsPolicyUsers))
+ .register(CD_CONTENT_EXCHANGE))
+ .endpoint("http://localhost:1/_vti_bin/People.asmx", mockPeople);
+
+ adaptor = new SharePointAdaptor(siteDataFactory,
+ new UnsupportedHttpClient(), executorFactory);
+ adaptor.init(new MockAdaptorContext(config, pusher));
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ GetContentsResponse response = new GetContentsResponse(baos);
+ adaptor.getDocContent(new GetContentsRequest(new DocId("")), response);
+ String[] permitUsers = new String[] {"GDC-PSL\\Administrator",
+ "GDC-PSL\\spuser1", "NT AUTHORITY\\LOCAL SERVICE",
+ "GSA-CONNECTORS\\Administrator"};
+ String[] permitGroups= new String[] {"GSA-CONNECTORS\\domain users"};
+ assertEquals(new Acl.Builder()
+ .setEverythingCaseInsensitive()
+ .setInheritanceType(Acl.InheritanceType.PARENT_OVERRIDES)
+ .setPermitUsers(users(permitUsers))
+ .setPermitGroups(groups(permitGroups)).build(),
response.getAcl());
assertNull(response.getDisplayUrl());
}
@@ -461,11 +523,13 @@
.endpoint(SITES_SITECOLLECTION_ENDPOINT, MockSiteData.blank()
.register(SITES_SITECOLLECTION_URLSEG_EXCHANGE)
.register(SITES_SITECOLLECTION_S_CONTENT_EXCHANGE
- .replaceInContent("Name=\"spuser1\"", "Name=\"GDC-PSL\\group\"")
+ .replaceInContent("LoginName=\"GDC-PSL\\spuser1\"",
+ "LoginName=\"GDC-PSL\\group\"")
.replaceInContent("IsDomainGroup=\"False\"",
"IsDomainGroup=\"True\""))
.register(SITES_SITECOLLECTION_SC_CONTENT_EXCHANGE
- .replaceInContent("Name=\"spuser1\"", "Name=\"GDC-PSL\\group\"")
+ .replaceInContent("LoginName=\"GDC-PSL\\spuser1\"",
+ "LoginName=\"GDC-PSL\\group\"")
.replaceInContent("IsDomainGroup=\"False\"",
"IsDomainGroup=\"True\"")));
@@ -634,7 +698,8 @@
GetContentsResponse response = new GetContentsResponse(baos);
adaptor.new SiteAdaptor("http://localhost:1/sites/SiteCollection",
"http://localhost:1/sites/SiteCollection", siteData,
- new UnsupportedUserGroupSoap(), Callables.returning(memberIdMapping),
+ new UnsupportedUserGroupSoap(), new UnsupportedPeopleSoap(),
+ Callables.returning(memberIdMapping),
new UnsupportedCallable<MemberIdMapping>())
.getDocContent(request, response);
String responseString = new String(baos.toByteArray(), charset);
@@ -677,7 +742,7 @@
GetContentsResponse response = new GetContentsResponse(baos);
adaptor.new SiteAdaptor("http://localhost:1/sites/SiteCollection",
"http://localhost:1/sites/SiteCollection", siteData,
- new UnsupportedUserGroupSoap(),
+ new UnsupportedUserGroupSoap(), new UnsupportedPeopleSoap(),
new UnsupportedCallable<MemberIdMapping>(),
new UnsupportedCallable<MemberIdMapping>())
.getDocContent(request, response);
@@ -720,7 +785,7 @@
GetContentsResponse response = new GetContentsResponse(baos);
adaptor.new SiteAdaptor("http://localhost:1/sites/SiteCollection",
"http://localhost:1/sites/SiteCollection", siteData,
- new UnsupportedUserGroupSoap(),
+ new UnsupportedUserGroupSoap(), new UnsupportedPeopleSoap(),
new UnsupportedCallable<MemberIdMapping>(),
new UnsupportedCallable<MemberIdMapping>())
.getDocContent(request, response);
@@ -770,7 +835,8 @@
GetContentsResponse response = new GetContentsResponse(baos);
adaptor.new SiteAdaptor("http://localhost:1/sites/SiteCollection",
"http://localhost:1/sites/SiteCollection", siteData,
- new UnsupportedUserGroupSoap(), Callables.returning(memberIdMapping),
+ new UnsupportedUserGroupSoap(), new UnsupportedPeopleSoap(),
+ Callables.returning(memberIdMapping),
new UnsupportedCallable<MemberIdMapping>())
.getDocContent(request, response);
String responseString = new String(baos.toByteArray(), charset);
@@ -884,7 +950,8 @@
GetContentsResponse response = new GetContentsResponse(baos);
adaptor.new SiteAdaptor("http://localhost:1/sites/SiteCollection",
"http://localhost:1/sites/SiteCollection", siteData,
- new UnsupportedUserGroupSoap(), Callables.returning(memberIdMapping),
+ new UnsupportedUserGroupSoap(), new UnsupportedPeopleSoap(),
+ Callables.returning(memberIdMapping),
new UnsupportedCallable<MemberIdMapping>())
.getDocContent(request, response);
assertNull(response.getAcl());
@@ -944,7 +1011,8 @@
GetContentsResponse response = new GetContentsResponse(baos);
adaptor.new SiteAdaptor("http://localhost:1/sites/SiteCollection",
"http://localhost:1/sites/SiteCollection", siteData,
- mockUserGroupSoap, Callables.returning(memberIdMapping),
+ mockUserGroupSoap, new UnsupportedPeopleSoap(),
+ Callables.returning(memberIdMapping),
adaptor.new SiteUserIdMappingCallable(
"http://localhost:1/sites/SiteCollection"))
.getDocContent(request, response);
@@ -1008,7 +1076,7 @@
GetContentsResponse response = new GetContentsResponse(baos);
adaptor.new SiteAdaptor("http://localhost:1/sites/SiteCollection",
"http://localhost:1/sites/SiteCollection",
- siteData, new UnsupportedUserGroupSoap(),
+ siteData, new UnsupportedUserGroupSoap(), new UnsupportedPeopleSoap(),
Callables.returning(memberIdMapping),
new UnsupportedCallable<MemberIdMapping>())
.getDocContent(request, response);
@@ -1051,7 +1119,7 @@
GetContentsResponse response = new GetContentsResponse(baos);
adaptor.new SiteAdaptor("http://localhost:1/sites/SiteCollection",
"http://localhost:1/sites/SiteCollection",
- siteData, new UnsupportedUserGroupSoap(),
+ siteData, new UnsupportedUserGroupSoap(), new UnsupportedPeopleSoap(),
Callables.returning(memberIdMapping),
new UnsupportedCallable<MemberIdMapping>())
.getDocContent(request, response);
@@ -1328,7 +1396,7 @@
adaptor.new SiteAdaptor(
"http://localhost:1/sites/SiteCollection",
"http://localhost:1/sites/SiteCollection", new UnsupportedSiteData(),
- new UnsupportedUserGroupSoap(),
+ new UnsupportedUserGroupSoap(), new UnsupportedPeopleSoap(),
new UnsupportedCallable<MemberIdMapping>(),
new UnsupportedCallable<MemberIdMapping>())
.getModifiedDocIds(result, pusher);
@@ -1444,6 +1512,71 @@
throw new UnsupportedOperationException();
}
}
+
+ private abstract static class DelegatingPeopleSoap implements PeopleSoap {
+ protected abstract PeopleSoap delegate();
+
+ @Override
+ public boolean isClaimsMode() {
+ return delegate().isClaimsMode();
+ }
+
+ @Override
+ public ArrayOfPrincipalInfo resolvePrincipals(
+ ArrayOfString aos, SPPrincipalType sppt, boolean bln) {
+ return delegate().resolvePrincipals(aos, sppt, bln);
+ }
+
+ @Override
+ public ArrayOfPrincipalInfo searchPrincipals(
+ String string, int i, SPPrincipalType sppt) {
+ return delegate().searchPrincipals(string, i, sppt);
+ }
+ }
+
+ private static class UnsupportedPeopleSoap extends DelegatingPeopleSoap {
+ private final String endpoint;
+
+ public UnsupportedPeopleSoap() {
+ this(null);
+ }
+
+ public UnsupportedPeopleSoap(String endpoint) {
+ this.endpoint = endpoint;
+ }
+
+ @Override
+ protected PeopleSoap delegate() {
+ if (endpoint == null) {
+ throw new UnsupportedOperationException();
+ } else {
+ throw new UnsupportedOperationException("Endpoint: " + endpoint);
+ }
+ }
+ }
+
+ private static class MockPeopleSoap extends UnsupportedPeopleSoap {
+ private final ArrayOfPrincipalInfo result;
+ public MockPeopleSoap() {
+ this.result = new ArrayOfPrincipalInfo();
+ }
+
+ @Override
+ public ArrayOfPrincipalInfo resolvePrincipals(
+ ArrayOfString aos, SPPrincipalType sppt, boolean bln) {
+ return result;
+ }
+
+ public void addToResult(String accountName, String dispalyName,
+ SPPrincipalType type) {
+ PrincipalInfo p = new PrincipalInfo();
+ p.setAccountName(accountName);
+ p.setDisplayName(dispalyName);
+ p.setIsResolved(true);
+ p.setPrincipalType(type);
+ result.getPrincipalInfo().add(p);
+ }
+ }
private static class MockUserGroupSoap extends UnsupportedUserGroupSoap {
final Users users;
@@ -1819,37 +1952,47 @@
private final SiteDataSoap siteData;
private final UserGroupSoap userGroup;
private final AuthenticationSoap authentication;
+ private final PeopleSoap people;
private final MockSoapFactory chain;
private MockSoapFactory(String expectedEndpoint, SiteDataSoap siteData,
- UserGroupSoap userGroup, AuthenticationSoap authentication,
- MockSoapFactory chain) {
+ UserGroupSoap userGroup, PeopleSoap people,
+ AuthenticationSoap authentication, MockSoapFactory chain) {
this.expectedEndpoint = expectedEndpoint;
this.siteData = siteData;
this.userGroup = userGroup;
+ this.people = people;
// Tests will always use windows authentication.
this.authentication = authentication;
this.chain = chain;
}
public static MockSoapFactory blank() {
- return new MockSoapFactory(null, null, null, null, null);
+ return new MockSoapFactory(null, null, null, null, null, null);
}
public MockSoapFactory endpoint(String expectedEndpoint,
SiteDataSoap siteData) {
- return new MockSoapFactory(expectedEndpoint, siteData, null, null, this);
+ return new MockSoapFactory(
+ expectedEndpoint, siteData, null, null, null, this);
}
public MockSoapFactory endpoint(String expectedEndpoint,
UserGroupSoap userGroup) {
- return new MockSoapFactory(expectedEndpoint, null, userGroup, null, this);
+ return new MockSoapFactory(
+ expectedEndpoint, null, userGroup, null, null, this);
+ }
+
+ public MockSoapFactory endpoint(String expectedEndpoint,
+ PeopleSoap people) {
+ return new MockSoapFactory(
+ expectedEndpoint, null, null, people, null, this);
}
public MockSoapFactory endpoint(String expectedEndpoint,
AuthenticationSoap authentication) {
return new MockSoapFactory(
- expectedEndpoint, null, null, authentication, this);
+ expectedEndpoint, null, null, null, authentication, this);
}
@Override
@@ -1887,6 +2030,17 @@
}
return chain.newUserGroup(endpoint);
}
+
+ @Override
+ public PeopleSoap newPeople(String endpoint) {
+ if (chain == null) {
+ return new UnsupportedPeopleSoap(endpoint);
+ }
+ if (expectedEndpoint.equals(endpoint) && people != null) {
+ return people;
+ }
+ return chain.newPeople(endpoint);
+ }
}
private static class ReferenceSiteData extends DelegatingSiteData {