Author: kwright
Date: Tue Oct 22 12:44:48 2013
New Revision: 1534617
URL: http://svn.apache.org/r1534617
Log:
Flesh out SharePoint authority, far enough so we can use it for actual
debugging.
Modified:
manifoldcf/branches/CONNECTORS-754/connectors/sharepoint/connector/src/main/java/org/apache/manifoldcf/authorities/authorities/sharepoint/SPSProxyHelper.java
manifoldcf/branches/CONNECTORS-754/connectors/sharepoint/connector/src/main/java/org/apache/manifoldcf/authorities/authorities/sharepoint/SharePointAuthority.java
Modified:
manifoldcf/branches/CONNECTORS-754/connectors/sharepoint/connector/src/main/java/org/apache/manifoldcf/authorities/authorities/sharepoint/SPSProxyHelper.java
URL:
http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-754/connectors/sharepoint/connector/src/main/java/org/apache/manifoldcf/authorities/authorities/sharepoint/SPSProxyHelper.java?rev=1534617&r1=1534616&r2=1534617&view=diff
==============================================================================
---
manifoldcf/branches/CONNECTORS-754/connectors/sharepoint/connector/src/main/java/org/apache/manifoldcf/authorities/authorities/sharepoint/SPSProxyHelper.java
(original)
+++
manifoldcf/branches/CONNECTORS-754/connectors/sharepoint/connector/src/main/java/org/apache/manifoldcf/authorities/authorities/sharepoint/SPSProxyHelper.java
Tue Oct 22 12:44:48 2013
@@ -103,7 +103,7 @@ public class SPSProxyHelper {
/**
* Get the access tokens for a user principal.
*/
- public String[] getAccessTokens(String site )
+ public List<String> getAccessTokens( String site, String userLoginName )
throws ManifoldCFException
{
try
@@ -114,14 +114,112 @@ public class SPSProxyHelper {
UserGroupWS userService = new UserGroupWS( baseUrl + site, userName,
password, configuration, httpClient );
com.microsoft.schemas.sharepoint.soap.directory.UserGroupSoap userCall =
userService.getUserGroupSoapHandler( );
- // Temporary, so that the exceptions still get thrown
- String userLogin = "xxx";
-
com.microsoft.schemas.sharepoint.soap.directory.GetUserInfoResponseGetUserInfoResult
userResp = userCall.getUserInfo( userLogin );
- org.apache.axis.message.MessageElement[] userList = userResp.get_any();
+
com.microsoft.schemas.sharepoint.soap.directory.GetUserInfoResponseGetUserInfoResult
userResp = userCall.getUserInfo( userLoginName );
+ org.apache.axis.message.MessageElement[] usersList = userResp.get_any();
+
+ /* Response looks like this:
+ <GetUserInfo
xmlns="http://schemas.microsoft.com/sharepoint/soap/directory/">
+ <User ID="4"
Sid="S-1-5-21-2127521184-1604012920-1887927527-34577" Name="User1_Display_Name"
+ LoginName="DOMAIN\User1_Alias" Email="User1_E-mail"
+ Notes="Notes" IsSiteAdmin="False" IsDomainGroup="False" />
+ </GetUserInfo>
+ */
+
+ if (usersList.length != 1)
+ throw new ManifoldCFException("Bad response - expecting one outer
'GetUserInfo' node, saw "+Integer.toString(usersList.length));
+
+ if (Logging.authorityConnectors.isDebugEnabled()){
+ Logging.authorityConnectors.debug("SharePoint authority: getUserInfo
xml response: '" + usersList[0].toString() + "'");
+ }
+
+ MessageElement users = usersList[0];
+ if (!users.getElementName().getLocalName().equals("GetUserInfo"))
+ throw new ManifoldCFException("Bad response - outer node should have
been 'GetUserInfo' node");
+
+ String userID = null;
+
+ Iterator userIter = users.getChildElements();
+ while (userIter.hasNext())
+ {
+ MessageElement child = (MessageElement)userIter.next();
+ if (child.getElementName().getLocalName().equals("User"))
+ {
+ userID = child.getAttribute("ID");
+ }
+ }
+
+ // If userID is null, no such user
+ if (userID == null)
+ return null;
+
+ List<String> accessTokens = new ArrayList<String>();
+ accessTokens.add("U"+userID);
+
+
com.microsoft.schemas.sharepoint.soap.directory.GetGroupCollectionFromUserResponseGetGroupCollectionFromUserResult
userGroupResp =
+ userCall.getGroupCollectionFromUser( userLoginName );
+ org.apache.axis.message.MessageElement[] groupsList =
userGroupResp.get_any();
+
+ /* Response looks like this:
+ <GetGroupCollectionFromUser xmlns=
+ "http://schemas.microsoft.com/sharepoint/soap/directory/">
+ <Groups>
+ <Group ID="3" Name="Group1" Description="Description"
OwnerID="1"
+ OwnerIsUser="False" />
+ <Group ID="15" Name="Group2" Description="Description"
+ OwnerID="12" OwnerIsUser="True" />
+ <Group ID="16" Name="Group3" Description="Description"
+ OwnerID="7" OwnerIsUser="False" />
+ </Groups>
+ </GetGroupCollectionFromUser>
+ */
+
+ if (groupsList.length != 1)
+ throw new ManifoldCFException("Bad response - expecting one outer
'GetGroupCollectionFromUser' node, saw "+Integer.toString(groupsList.length));
+
+ if (Logging.authorityConnectors.isDebugEnabled()){
+ Logging.authorityConnectors.debug("SharePoint authority:
getGroupCollectionFromUser xml response: '" + groupsList[0].toString() + "'");
+ }
+
+ MessageElement groups = groupsList[0];
+ if
(!users.getElementName().getLocalName().equals("GetGroupCollectionFromUser"))
+ throw new ManifoldCFException("Bad response - outer node should have
been 'GetGroupCollectionFromUser' node");
+
+ Iterator groupsIter = groups.getChildElements();
+ while (groupsIter.hasNext())
+ {
+ MessageElement child = (MessageElement)groupsIter.next();
+ if (child.getElementName().getLocalName().equals("Groups"))
+ {
+ Iterator groupIter = child.getChildElements();
+ while (groupIter.hasNext())
+ {
+ MessageElement group = (MessageElement)groupIter.next();
+ if (group.getElementName().getLocalName().equals("Group"))
+ {
+ String groupID = group.getAttribute("ID");
+ String groupName = group.getAttribute("Name");
+ // Add to the access token list
+ accessTokens.add("G"+groupID);
+ }
+ }
+ }
+ }
+
+
com.microsoft.schemas.sharepoint.soap.directory.GetRoleCollectionFromUserResponseGetRoleCollectionFromUserResult
userRoleResp =
+ userCall.getRoleCollectionFromUser( userLoginName );
+ org.apache.axis.message.MessageElement[] rolesList =
userRoleResp.get_any();
+
+ if (rolesList.length != 1)
+ throw new ManifoldCFException("Bad response - expecting one outer
'GetRoleCollectionFromUser' node, saw "+Integer.toString(rolesList.length));
+
+ if (Logging.authorityConnectors.isDebugEnabled()){
+ Logging.authorityConnectors.debug("SharePoint authority:
getRoleCollectionFromUser xml response: '" + rolesList[0].toString() + "'");
+ }
+ // Not specified in doc and must be determined experimentally
// MHL
- return new String[0];
+ return accessTokens;
}
catch (java.net.MalformedURLException e)
{
Modified:
manifoldcf/branches/CONNECTORS-754/connectors/sharepoint/connector/src/main/java/org/apache/manifoldcf/authorities/authorities/sharepoint/SharePointAuthority.java
URL:
http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-754/connectors/sharepoint/connector/src/main/java/org/apache/manifoldcf/authorities/authorities/sharepoint/SharePointAuthority.java?rev=1534617&r1=1534616&r2=1534617&view=diff
==============================================================================
---
manifoldcf/branches/CONNECTORS-754/connectors/sharepoint/connector/src/main/java/org/apache/manifoldcf/authorities/authorities/sharepoint/SharePointAuthority.java
(original)
+++
manifoldcf/branches/CONNECTORS-754/connectors/sharepoint/connector/src/main/java/org/apache/manifoldcf/authorities/authorities/sharepoint/SharePointAuthority.java
Tue Oct 22 12:44:48 2013
@@ -395,9 +395,59 @@ public class SharePointAuthority extends
int index = userName.indexOf("@");
if (index == -1)
throw new ManifoldCFException("Username is in unexpected form (no @):
'"+userName+"'");
+
String userPart = userName.substring(0,index);
String domainPart = userName.substring(index+1);
+
+ List<String> theGroups = new ArrayList<String>();
+
+ // First, look up user in SharePoint.
+ getSharePointSession();
+ List<String> sharePointTokens = proxy.getAccessTokens("/", domainPart +
"\\" + userPart);
+ if (sharePointTokens == null)
+ return RESPONSE_USERNOTFOUND;
+ theGroups.addAll(sharePointTokens);
+
+ // Use AD only if Claim Space
+ if (isClaimSpace)
+ {
+ try
+ {
+ List<String> adTokens = getADTokens(userPart,domainPart);
+ // User not present in AD is perfectly OK provided the user exists in
SharePoint
+ if (adTokens != null)
+ theGroups.addAll(adTokens);
+ }
+ catch (NameNotFoundException e)
+ {
+ // This means that the user doesn't exist
+ return RESPONSE_USERNOTFOUND;
+ }
+ catch (NamingException e)
+ {
+ // Unreachable
+ return RESPONSE_UNREACHABLE;
+ }
+ }
+ return new AuthorizationResponse(theGroups.toArray(new
String[0]),AuthorizationResponse.RESPONSE_OK);
+ }
+
+ /** Obtain the default access tokens for a given user name.
+ *@param userName is the user name or identifier.
+ *@return the default response tokens, presuming that the connect method
fails.
+ */
+ @Override
+ public AuthorizationResponse getDefaultAuthorizationResponse(String userName)
+ {
+ // The default response if the getConnection method fails
+ return RESPONSE_UNREACHABLE;
+ }
+
+ /** Get the AD-derived access tokens for a user and domain */
+ protected List<String> getADTokens(String userPart, String domainPart)
+ throws NameNotFoundException, NamingException, ManifoldCFException
+ {
// Now, look through the rules for the matching domain controller
String domainController = null;
for (DCRule rule : dCRules)
@@ -410,26 +460,23 @@ public class SharePointAuthority extends
break;
}
}
+
if (domainController == null)
- {
- // No domain controller found for the user, so return "user not found".
- return RESPONSE_USERNOTFOUND;
- }
+ // No AD user
+ return null;
// Look up connection parameters
DCConnectionParameters dcParams =
dCConnectionParameters.get(domainController);
if (dcParams == null)
- {
- // No domain controller, even though it's mentioned in a rule
- return RESPONSE_USERNOTFOUND;
- }
-
+ // No AD user
+ return null;
+
// Use the complete fqn if the field is the "userPrincipalName"
String userACLsUsername = dcParams.getUserACLsUsername();
if (userACLsUsername != null &&
userACLsUsername.equals("userPrincipalName")){
- userPart = userName;
+ userPart = userName;
}
-
+
//Build the DN searchBase from domain part
StringBuilder domainsb = new StringBuilder();
int j = 0;
@@ -448,104 +495,75 @@ public class SharePointAuthority extends
j = k+1;
}
- try
- {
- // Establish a session with the selected domain controller
- LdapContext ctx = createDCSession(domainController);
-
- //Get DistinguishedName (for this method we are using DomainPart as a
searchBase ie: DC=qa-ad-76,DC=metacarta,DC=com")
- String searchBase = getDistinguishedName(ctx, userPart,
domainsb.toString(), userACLsUsername);
- if (searchBase == null)
- return RESPONSE_USERNOTFOUND;
+ // Establish a session with the selected domain controller
+ LdapContext ctx = createDCSession(domainController);
+
+ //Get DistinguishedName (for this method we are using DomainPart as a
searchBase ie: DC=qa-ad-76,DC=metacarta,DC=com")
+ String searchBase = getDistinguishedName(ctx, userPart,
domainsb.toString(), userACLsUsername);
+ if (searchBase == null)
+ return null;
- //specify the LDAP search filter
- String searchFilter = "(objectClass=user)";
+ //specify the LDAP search filter
+ String searchFilter = "(objectClass=user)";
- //Create the search controls for finding the access tokens
- SearchControls searchCtls = new SearchControls();
+ //Create the search controls for finding the access tokens
+ SearchControls searchCtls = new SearchControls();
- //Specify the search scope, must be base level search for tokenGroups
- searchCtls.setSearchScope(SearchControls.OBJECT_SCOPE);
-
- //Specify the attributes to return
- String returnedAtts[]={"tokenGroups","objectSid"};
- searchCtls.setReturningAttributes(returnedAtts);
+ //Specify the search scope, must be base level search for tokenGroups
+ searchCtls.setSearchScope(SearchControls.OBJECT_SCOPE);
+
+ //Specify the attributes to return
+ String returnedAtts[]={"tokenGroups","objectSid"};
+ searchCtls.setReturningAttributes(returnedAtts);
- //Search for tokens. Since every user *must* have a SID, the "no user"
detection should be safe.
- NamingEnumeration answer = ctx.search(searchBase, searchFilter,
searchCtls);
+ //Search for tokens. Since every user *must* have a SID, the "no user"
detection should be safe.
+ NamingEnumeration answer = ctx.search(searchBase, searchFilter,
searchCtls);
- ArrayList theGroups = new ArrayList();
+ List<String> theGroups = new ArrayList<String>();
- //Loop through the search results
- while (answer.hasMoreElements())
+ //Loop through the search results
+ while (answer.hasMoreElements())
+ {
+ SearchResult sr = (SearchResult)answer.next();
+
+ //the sr.GetName should be null, as it is relative to the base object
+
+ Attributes attrs = sr.getAttributes();
+ if (attrs != null)
{
- SearchResult sr = (SearchResult)answer.next();
-
- //the sr.GetName should be null, as it is relative to the base object
-
- Attributes attrs = sr.getAttributes();
- if (attrs != null)
+ try
{
- try
+ for (NamingEnumeration ae = attrs.getAll();ae.hasMore();)
{
- for (NamingEnumeration ae = attrs.getAll();ae.hasMore();)
+ Attribute attr = (Attribute)ae.next();
+ for (NamingEnumeration e = attr.getAll();e.hasMore();)
{
- Attribute attr = (Attribute)ae.next();
- for (NamingEnumeration e = attr.getAll();e.hasMore();)
- {
- theGroups.add(sid2String((byte[])e.next()));
- }
+ theGroups.add(groupTokenFromSID(sid2String((byte[])e.next())));
}
-
- }
- catch (NamingException e)
- {
- throw new ManifoldCFException(e.getMessage(),e);
}
-
+ }
+ catch (NamingException e)
+ {
+ throw new ManifoldCFException(e.getMessage(),e);
}
+
}
-
- if (theGroups.size() == 0)
- return RESPONSE_USERNOTFOUND;
-
- // All users get certain well-known groups
- theGroups.add("S-1-1-0");
-
- String[] tokens = new String[theGroups.size()];
- int k = 0;
- while (k < tokens.length)
- {
- tokens[k] = (String)theGroups.get(k);
- k++;
- }
-
- return new
AuthorizationResponse(tokens,AuthorizationResponse.RESPONSE_OK);
-
- }
- catch (NameNotFoundException e)
- {
- // This means that the user doesn't exist
- return RESPONSE_USERNOTFOUND;
- }
- catch (NamingException e)
- {
- // Unreachable
- return RESPONSE_UNREACHABLE;
}
+
+ if (theGroups.size() == 0)
+ return null;
+
+ // User is in AD, so add the 'everyone' group
+ theGroups.add(groupTokenFromSID("S-1-1-0"));
+ return theGroups;
}
- /** Obtain the default access tokens for a given user name.
- *@param userName is the user name or identifier.
- *@return the default response tokens, presuming that the connect method
fails.
- */
- @Override
- public AuthorizationResponse getDefaultAuthorizationResponse(String userName)
+ protected String groupTokenFromSID(String SID)
{
- // The default response if the getConnection method fails
- return RESPONSE_UNREACHABLE;
+ // MHL; called only if Claim Space enabled
+ return SID;
}
-
+
// UI support methods.
//
// These support methods are involved in setting up authority connection
configuration information. The configuration methods cannot assume that the