// 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 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";

        #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
                {
                    ServicePointManager.ServerCertificateValidationCallback +=
                        new RemoteCertificateValidationCallback(ValidateCertificate);

                    using (SPPermissionsService.Permissions service = new SPPermissionsService.Permissions())
                    {
                        service.Url = SPContext.Current.Web.Url + "/_vti_bin/Permissions.asmx";
                        service.Credentials = System.Net.CredentialCache.DefaultCredentials;

                        retVal = service.GetPermissionCollection(objectName, objectType);
                    }
                }
            }
            catch (SoapException soapEx)
            {
                throw soapEx;
            }
            catch (Exception ex)
            {
                EventLog.WriteEntry("MCPermissions.asmx", ex.Message);
                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 (SPSite site = new SPSite(SPContext.Current.Web.Url))
                {
                    using (SPWeb oWebsiteRoot = site.OpenWeb())
                    {
                        if (oWebsiteRoot != null)
                        {

                            oWebsiteRoot.Lists.IncludeRootFolder = true;
                            SPList oList = oWebsiteRoot.Lists[new Guid(listName)];

                            SPQuery listQuery = new SPQuery();
                            listQuery.QueryThrottleMode = SPQueryThrottleOption.Override;
                            listQuery.ViewAttributes = "Scope=\"Recursive\"";
                            listQuery.ViewFields = string.Concat(
                                   "<FieldRef Name='FileRef' />");


                            listQuery.RowLimit = 1000;

                            uint counter = 0;
                            do
                            {
                                if (counter >= startRowParam + rowLimitParam)
                                    break;

                                // Will this work?  Or will it reset something unexpected?
                                if (startRowParam + rowLimitParam - counter < 1000)
                                    listQuery.RowLimit = startRowParam + rowLimitParam - counter;

                                SPListItemCollection collListItems = oList.GetItems(listQuery);

                                XmlDocument doc = new XmlDocument();
                                retVal = doc.CreateElement("GetListItems", 
                                    "http://schemas.microsoft.com/sharepoint/soap/directory/");
                                XmlNode getListItemsNode = doc.CreateElement("GetListItemsResponse");

                                foreach (SPListItem oListItem in collListItems)
                                {
                                    if (counter >= startRowParam)
                                    {
                                        XmlNode resultNode = doc.CreateElement("GetListItemsResult");
                                        XmlAttribute idAttribute = doc.CreateAttribute("FileRef");
                                        idAttribute.Value = oListItem.Url;
                                        resultNode.Attributes.Append(idAttribute);
                                        getListItemsNode.AppendChild(resultNode);
                                    }
                                    counter++;
                                }
                                
                                retVal.AppendChild(getListItemsNode);
                            } while (listQuery.ListItemCollectionPosition != null);
                        }
                    }

                }
            }
            catch (SoapException soapEx)
            {
                throw soapEx;
            }
            catch (Exception ex)
            {
                EventLog.WriteEntry("MCPermissions.asmx", ex.Message);
                throw RaiseException(ex.Message, "1010", ex.Source);
            }

            return retVal;
        }
        
        #endregion

        #region Private Methods

        /// <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)
        {
            XmlNode retVal = null;

            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);

                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
    }
}