blob: aa1cf66c2a9d9489f4203244627f8a7adce61cf1 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Read the file "readme.txt" in this directory for a description of what this
// web service does and why it is needed.
using System;
using System.Data;
using System.Web;
using System.Collections;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.ComponentModel;
using System.Security.Permissions;
using System.Xml;
using System.Diagnostics;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
namespace MetaCarta.SharePoint.SoapServer
{
[WebService(Namespace = "http://microsoft.com/sharepoint/webpartpages/"),
WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1),
PermissionSet(SecurityAction.InheritanceDemand, Name = "FullTrust"),
PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")]
public class Permissions : System.Web.Services.WebService
{
#region Private Fields
private readonly string itemType = "Item";
private readonly string listType = "List";
private readonly string webType = "Web";
#endregion
#region Public Methods
[WebMethod(Description = "Returns the collection of permissions for a site, list, or list item.")]
public XmlNode GetPermissionCollection(string objectName, string objectType)
{
XmlNode retVal = null;
try
{
// Only handle requests for "item". Send all other requests to the SharePoint web service.
if (objectType.Equals(itemType))
{
retVal = GetItemPermissions(objectName);
}
else if (objectType.Equals(listType))
{
retVal = GetListPermissions(objectName);
}
else if (objectType.Equals(webType))
{
retVal = GetWebPermissions(objectName);
}
else
{
throw new Exception("Unknown permission type: " + objectType);
}
}
catch (Exception ex)
{
SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("MCPermissions.asmx", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, "Error: "+ex.Message+"; SPContext.Current.Web.Url='"+SPContext.Current.Web.Url+"'", ex.StackTrace);
throw RaiseException(ex.Message, "1000", ex.Source);
}
return retVal;
}
[WebMethod(Description = "Returns the list of contents of a library without interference from administrator-set limits.")]
public XmlNode GetListItems(string listName, string startRow, string rowLimit)
{
XmlNode retVal = null;
try
{
uint startRowParam = Convert.ToUInt32(startRow);
uint rowLimitParam = Convert.ToUInt32(rowLimit);
using (SPWeb oWebsiteRoot = SPContext.Current.Web)
{
if (oWebsiteRoot != null)
{
oWebsiteRoot.Lists.IncludeRootFolder = true;
SPList oList = oWebsiteRoot.Lists[new Guid(listName)];
SPQuery listQuery = new SPQuery();
listQuery.Query = "<OrderBy Override=\"TRUE\"><FieldRef Name=\"FileRef\" /></OrderBy>";
listQuery.QueryThrottleMode = SPQueryThrottleOption.Override;
listQuery.ViewAttributes = "Scope=\"Recursive\"";
listQuery.ViewFields = "<FieldRef Name='FileRef' />";
listQuery.RowLimit = 1000;
XmlDocument doc = new XmlDocument();
retVal = doc.CreateElement("GetListItems",
"http://schemas.microsoft.com/sharepoint/soap/directory/");
XmlNode getListItemsNode = doc.CreateElement("GetListItemsResponse");
uint counter = 0;
do
{
if (counter >= startRowParam + rowLimitParam)
break;
SPListItemCollection collListItems = oList.GetItems(listQuery);
foreach (SPListItem oListItem in collListItems)
{
if (counter >= startRowParam && counter < startRowParam + rowLimitParam)
{
XmlNode resultNode = doc.CreateElement("GetListItemsResult");
XmlAttribute idAttribute = doc.CreateAttribute("FileRef");
idAttribute.Value = oListItem.Url;
resultNode.Attributes.Append(idAttribute);
getListItemsNode.AppendChild(resultNode);
}
counter++;
}
listQuery.ListItemCollectionPosition = collListItems.ListItemCollectionPosition;
} while (listQuery.ListItemCollectionPosition != null);
retVal.AppendChild(getListItemsNode);
}
}
}
catch (SoapException soapEx)
{
throw soapEx;
}
catch (Exception ex)
{
SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("MCPermissions.asmx", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, "Error: "+ex.Message, ex.StackTrace);
throw RaiseException(ex.Message, "1010", ex.Source);
}
return retVal;
}
[WebMethod(Description = "Returns the list of subsites reliably on SharePoint 2010 AWS systems.")]
public XmlNode GetSites()
{
XmlNode retVal = null;
try
{
using (SPWeb oWebsiteRoot = SPContext.Current.Web)
{
if (oWebsiteRoot != null)
{
XmlDocument doc = new XmlDocument();
retVal = doc.CreateElement("GetSites",
"http://schemas.microsoft.com/sharepoint/soap/directory/");
XmlNode getSitesNode = doc.CreateElement("GetSitesResponse");
foreach (SPWeb oWeb in oWebsiteRoot.Webs)
{
XmlNode resultNode = doc.CreateElement("GetSitesResult");
XmlAttribute urlAttribute = doc.CreateAttribute("URL");
urlAttribute.Value = oWeb.Url;
resultNode.Attributes.Append(urlAttribute);
XmlAttribute nameAttribute = doc.CreateAttribute("Name");
nameAttribute.Value = oWeb.Title;
resultNode.Attributes.Append(nameAttribute);
getSitesNode.AppendChild(resultNode);
}
retVal.AppendChild(getSitesNode);
}
}
}
catch (SoapException soapEx)
{
throw soapEx;
}
catch (Exception ex)
{
SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("MCPermissions.asmx", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, "Error: "+ex.Message, ex.StackTrace);
throw RaiseException(ex.Message, "1020", ex.Source);
}
return retVal;
}
#endregion
#region Private Methods
/// <summary>
/// Given the name of a list, return an XML fragment describing the set of permissions
/// for the specified list.
/// </summary>
/// <param name="itemName">A string containing the name of a list item</param>
/// <returns>An XML fragment</returns>
private XmlNode GetListPermissions(string listName)
{
if (string.IsNullOrEmpty(listName))
throw RaiseException("Parameter 'objectName' cannot be null or empty.", "2000", "GetPermissionCollection");
using (SPWeb site = SPContext.Current.Web)
{
SPList item = site.GetList(listName);
return PopulateResponse(item);
}
}
/// <summary>
/// Given the current site, return an XML fragment describing the set of permissions
/// for the site.
/// </summary>
/// <param name="itemName">A string containing the name of a list item</param>
/// <returns>An XML fragment</returns>
private XmlNode GetWebPermissions(string siteName)
{
if (!siteName.Equals("/"))
throw RaiseException("Parameter 'objectName' must be /", "2000", "GetPermissionCollection");
using (SPWeb site = SPContext.Current.Web)
{
return PopulateResponse(site);
}
}
/// <summary>
/// Given the name of a list item, return an XML fragment describing the set of permissions
/// for the specified list item.
/// </summary>
/// <param name="itemName">A string containing the name of a list item</param>
/// <returns>An XML fragment</returns>
private XmlNode GetItemPermissions(string itemName)
{
if (string.IsNullOrEmpty(itemName))
throw RaiseException("Parameter 'objectName' cannot be null or empty.", "2000", "GetPermissionCollection");
using (SPWeb site = SPContext.Current.Web)
{
SPListItem item = site.GetListItem(itemName);
return PopulateResponse(item);
}
}
private XmlNode PopulateResponse(SPSecurableObject item)
{
XmlNode retVal = null;
if (item.RoleAssignments.Count > 0)
{
XmlDocument doc = new XmlDocument();
retVal = doc.CreateElement("GetPermissionCollection",
"http://schemas.microsoft.com/sharepoint/soap/directory/");
XmlNode permissionsNode = doc.CreateElement("Permissions");
// A list item can have one or more role assignments. Each role assignment
// represents a member (user or group) with one or more permissions.
// The code below creates a Permission node for every member-permission assignment.
foreach (SPRoleAssignment assignment in item.RoleAssignments)
{
SPPrincipal member = assignment.Member;
foreach (SPRoleDefinition roleDefinition in assignment.RoleDefinitionBindings)
{
XmlNode permissionNode = CreatePermissionNode(doc, member, roleDefinition);
permissionsNode.AppendChild(permissionNode);
}
retVal.AppendChild(permissionsNode);
}
}
return retVal;
}
private XmlNode CreatePermissionNode(XmlDocument doc, SPPrincipal member, SPRoleDefinition roleDefinition)
{
XmlNode retVal = doc.CreateElement("Permission");
XmlAttribute memberIdAttribute = doc.CreateAttribute("MemberID");
memberIdAttribute.Value = member.ID.ToString();
retVal.Attributes.Append(memberIdAttribute);
XmlAttribute maskAttribute = doc.CreateAttribute("Mask");
int mask = (int)roleDefinition.BasePermissions;
maskAttribute.Value = mask.ToString();
retVal.Attributes.Append(maskAttribute);
XmlAttribute memberIsUserAttribute = doc.CreateAttribute("MemberIsUser");
memberIsUserAttribute.Value = member is SPUser ? "True" : "False";
retVal.Attributes.Append(memberIsUserAttribute);
XmlAttribute memberGlobalAttribute = doc.CreateAttribute("MemberGlobal");
string isGlobalValue = "True";
if (member is SPUser)
{
SPUser user = member as SPUser;
if (!user.IsDomainGroup)
isGlobalValue = "False";
}
memberGlobalAttribute.Value = isGlobalValue;
retVal.Attributes.Append(memberGlobalAttribute);
if (member is SPUser)
{
SPUser user = member as SPUser;
XmlAttribute userLoginAttribute = doc.CreateAttribute("UserLogin");
userLoginAttribute.Value = user.LoginName;
retVal.Attributes.Append(userLoginAttribute);
}
else
{
XmlAttribute groupNameAttribute = doc.CreateAttribute("GroupName");
groupNameAttribute.Value = member.Name;
retVal.Attributes.Append(groupNameAttribute);
}
return retVal;
}
private SoapException RaiseException(string errorMessage, string errorNumber, string errorSource)
{
SoapException retVal = null;
XmlDocument doc = new XmlDocument();
XmlNode root = doc.CreateNode(XmlNodeType.Element, SoapException.DetailElementName.Name,
SoapException.DetailElementName.Namespace);
XmlNode errorNode = doc.CreateNode(XmlNodeType.Element, "Error",
SoapException.DetailElementName.Namespace);
XmlNode errorNumberNode = doc.CreateNode(XmlNodeType.Element, "ErrorNumber",
SoapException.DetailElementName.Namespace);
errorNumberNode.InnerText = errorNumber;
XmlNode errorMessageNode = doc.CreateNode(XmlNodeType.Element, "ErrorMessage",
SoapException.DetailElementName.Namespace);
errorMessageNode.InnerText = errorMessage;
XmlNode errorSourceNode = doc.CreateNode(XmlNodeType.Element, "ErrorSource",
SoapException.DetailElementName.Namespace);
errorSourceNode.InnerText = errorSource;
errorNode.AppendChild(errorNumberNode);
errorNode.AppendChild(errorMessageNode);
errorNode.AppendChild(errorSourceNode);
root.AppendChild(errorNode);
retVal = new SoapException(errorMessage, SoapException.ClientFaultCode, Context.Request.Url.AbsoluteUri, root);
return retVal;
}
public static bool ValidateCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}
#endregion
}
}