A) Powershell support added within the provider B) Now returns the actual deployed language packs C) The PeoplePicker points to the organization OU and shows only the users from the tentant organization. A requirement when used with Exchange 2010 SP2 Addressbook Policies D) Shared SSL root added to use wild card certificates as part of hosting plan. When enabled the host name is generated. E) Search fix: Provisioning of localhost file where the server component is active. This system expected to be the search server. Within the local hostfile the sites are listed with their local ip address so the search server can resolve the site and crawl through their data. This component needs to be compiled with .NET 2.0 together with Provers.Base, OS.Windows2003, OS.Windows2008, Server.Utils, and Server components. Out standing is to update the build and deployment package for a dedicated deployment packaged so this component is using .NET 2.0, all other should be using .NET 4.0. This will eliminate the configuration circus that was required to get the .NET 4.0 version of this component working previously.
1027 lines
44 KiB
C#
1027 lines
44 KiB
C#
// Copyright (c) 2011, Outercurve Foundation.
|
|
// All rights reserved.
|
|
//
|
|
// Redistribution and use in source and binary forms, with or without modification,
|
|
// are permitted provided that the following conditions are met:
|
|
//
|
|
// - Redistributions of source code must retain the above copyright notice, this
|
|
// list of conditions and the following disclaimer.
|
|
//
|
|
// - Redistributions in binary form must reproduce the above copyright notice,
|
|
// this list of conditions and the following disclaimer in the documentation
|
|
// and/or other materials provided with the distribution.
|
|
//
|
|
// - Neither the name of the Outercurve Foundation nor the names of its
|
|
// contributors may be used to endorse or promote products derived from this
|
|
// software without specific prior written permission.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Specialized;
|
|
using System.Data;
|
|
using System.IO;
|
|
using System.Xml;
|
|
using System.Xml.Serialization;
|
|
using WebsitePanel.Providers;
|
|
using WebsitePanel.Providers.DNS;
|
|
using WebsitePanel.Providers.HostedSolution;
|
|
using WebsitePanel.Providers.SharePoint;
|
|
|
|
namespace WebsitePanel.EnterpriseServer.Code.SharePoint
|
|
{
|
|
/// <summary>
|
|
/// Exposes handful API on hosted SharePoint site collections management.
|
|
/// </summary>
|
|
public class HostedSharePointServerController : IImportController, IBackupController
|
|
{
|
|
private const int FILE_BUFFER_LENGTH = 5000000; // ~5MB
|
|
|
|
/// <summary>
|
|
/// Gets site collections in raw form.
|
|
/// </summary>
|
|
/// <param name="packageId">Package to which desired site collections belong.</param>
|
|
/// <param name="organizationId">Organization to which desired site collections belong.</param>
|
|
/// <param name="filterColumn">Filter column name.</param>
|
|
/// <param name="filterValue">Filter value.</param>
|
|
/// <param name="sortColumn">Sort column name.</param>
|
|
/// <param name="startRow">Row index to start from.</param>
|
|
/// <param name="maximumRows">Maximum number of rows to retrieve.</param>
|
|
/// <returns>Site collections that match.</returns>
|
|
public static SharePointSiteCollectionListPaged GetSiteCollectionsPaged(int packageId, int organizationId, string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows)
|
|
{
|
|
if (IsDemoMode)
|
|
{
|
|
SharePointSiteCollectionListPaged demoResult = new SharePointSiteCollectionListPaged();
|
|
demoResult.SiteCollections = GetSiteCollections(1, false);
|
|
demoResult.TotalRowCount = demoResult.SiteCollections.Count;
|
|
return demoResult;
|
|
}
|
|
|
|
SharePointSiteCollectionListPaged paged = new SharePointSiteCollectionListPaged();
|
|
DataSet result = PackageController.GetRawPackageItemsPaged(packageId, typeof(SharePointSiteCollection),
|
|
true, filterColumn, filterValue, sortColumn, startRow, Int32.MaxValue);
|
|
List<SharePointSiteCollection> items = PackageController.CreateServiceItemsList(result, 1).ConvertAll<SharePointSiteCollection>(delegate(ServiceProviderItem item) { return (SharePointSiteCollection)item; });
|
|
|
|
if (organizationId > 0)
|
|
{
|
|
items = items.FindAll(delegate(SharePointSiteCollection siteCollection) { return siteCollection.OrganizationId == organizationId; });
|
|
}
|
|
paged.TotalRowCount = items.Count;
|
|
|
|
if (items.Count > maximumRows)
|
|
{
|
|
items.RemoveRange(maximumRows, items.Count - maximumRows);
|
|
}
|
|
|
|
paged.SiteCollections = items;
|
|
|
|
return paged;
|
|
}
|
|
|
|
public static List<SharePointSiteCollection> GetSiteCollections(int organizationId)
|
|
{
|
|
Organization org = OrganizationController.GetOrganization(organizationId);
|
|
|
|
List<ServiceProviderItem> items = PackageController.GetPackageItemsByType(org.PackageId, typeof(SharePointSiteCollection), false);
|
|
items.ConvertAll<SharePointSiteCollection>(delegate(ServiceProviderItem item) { return (SharePointSiteCollection)item; });
|
|
List<SharePointSiteCollection> ret = new List<SharePointSiteCollection>();
|
|
foreach (ServiceProviderItem item in items)
|
|
{
|
|
SharePointSiteCollection siteCollection = item as SharePointSiteCollection;
|
|
if (siteCollection != null && siteCollection.OrganizationId == organizationId)
|
|
{
|
|
ret.Add(siteCollection);
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets list of supported languages by this installation of SharePoint.
|
|
/// </summary>
|
|
/// <returns>List of supported languages</returns>
|
|
public static int[] GetSupportedLanguages(int packageId)
|
|
{
|
|
if (IsDemoMode)
|
|
{
|
|
return new int[] { 1033 };
|
|
}
|
|
|
|
// Log operation.
|
|
TaskManager.StartTask("HOSTEDSHAREPOINT", "GET_LANGUAGES");
|
|
|
|
int serviceId = PackageController.GetPackageServiceId(packageId, ResourceGroups.HostedSharePoint);
|
|
if (serviceId == 0)
|
|
{
|
|
return new int[] { };
|
|
}
|
|
|
|
try
|
|
{
|
|
// Create site collection on server.
|
|
HostedSharePointServer hostedSharePointServer = GetHostedSharePointServer(serviceId);
|
|
return hostedSharePointServer.GetSupportedLanguages();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw TaskManager.WriteError(ex);
|
|
}
|
|
finally
|
|
{
|
|
TaskManager.CompleteTask();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets list of SharePoint site collections that belong to the package.
|
|
/// </summary>
|
|
/// <param name="packageId">Package that owns site collections.</param>
|
|
/// <param name="recursive">A value which shows whether nested spaces must be searched as well.</param>
|
|
/// <returns>List of found site collections.</returns>
|
|
public static List<SharePointSiteCollection> GetSiteCollections(int packageId, bool recursive)
|
|
{
|
|
if (IsDemoMode)
|
|
{
|
|
List<SharePointSiteCollection> demoResult = new List<SharePointSiteCollection>();
|
|
SharePointSiteCollection siteCollection1 = new SharePointSiteCollection();
|
|
siteCollection1.Id = 1;
|
|
siteCollection1.OrganizationId = 1;
|
|
siteCollection1.LocaleId = 1033;
|
|
siteCollection1.Name = "http://john.fabrikam.com";
|
|
siteCollection1.OwnerEmail = "john@fabrikam.com";
|
|
siteCollection1.OwnerLogin = "john@fabrikam.com";
|
|
siteCollection1.OwnerName = "John Smith";
|
|
siteCollection1.PhysicalAddress = "http://john.fabrikam.com";
|
|
siteCollection1.Title = "John Smith's Team Site";
|
|
siteCollection1.Url = "http://john.fabrikam.com";
|
|
demoResult.Add(siteCollection1);
|
|
SharePointSiteCollection siteCollection2 = new SharePointSiteCollection();
|
|
siteCollection2.Id = 2;
|
|
siteCollection1.OrganizationId = 1;
|
|
siteCollection2.LocaleId = 1033;
|
|
siteCollection2.Name = "http://mark.contoso.com";
|
|
siteCollection2.OwnerEmail = "mark@contoso.com";
|
|
siteCollection2.OwnerLogin = "mark@contoso.com";
|
|
siteCollection2.OwnerName = "Mark Jonsons";
|
|
siteCollection2.PhysicalAddress = "http://mark.contoso.com";
|
|
siteCollection2.Title = "Mark Jonsons' Blog";
|
|
siteCollection2.Url = "http://mark.contoso.com";
|
|
demoResult.Add(siteCollection2);
|
|
return demoResult;
|
|
}
|
|
|
|
|
|
List<ServiceProviderItem> items = PackageController.GetPackageItemsByType(packageId, typeof(SharePointSiteCollection), recursive);
|
|
return items.ConvertAll<SharePointSiteCollection>(delegate(ServiceProviderItem item) { return (SharePointSiteCollection)item; });
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets SharePoint site collection with given id.
|
|
/// </summary>
|
|
/// <param name="itemId">Site collection id within metabase.</param>
|
|
/// <returns>Site collection or null in case no such item exist.</returns>
|
|
public static SharePointSiteCollection GetSiteCollection(int itemId)
|
|
{
|
|
if (IsDemoMode)
|
|
{
|
|
return GetSiteCollections(1, false)[itemId - 1];
|
|
}
|
|
|
|
SharePointSiteCollection item = PackageController.GetPackageItem(itemId) as SharePointSiteCollection;
|
|
return item;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds SharePoint site collection.
|
|
/// </summary>
|
|
/// <param name="item">Site collection description.</param>
|
|
/// <returns>Created site collection id within metabase.</returns>
|
|
public static int AddSiteCollection(SharePointSiteCollection item)
|
|
{
|
|
|
|
// Check account.
|
|
int accountCheck = SecurityContext.CheckAccount(DemandAccount.NotDemo | DemandAccount.IsActive);
|
|
if (accountCheck < 0)
|
|
{
|
|
return accountCheck;
|
|
}
|
|
|
|
// Check package.
|
|
int packageCheck = SecurityContext.CheckPackage(item.PackageId, DemandPackage.IsActive);
|
|
if (packageCheck < 0)
|
|
{
|
|
return packageCheck;
|
|
}
|
|
|
|
// Check quota.
|
|
OrganizationStatistics orgStats = OrganizationController.GetOrganizationStatistics(item.OrganizationId);
|
|
//QuotaValueInfo quota = PackageController.GetPackageQuota(item.PackageId, Quotas.HOSTED_SHAREPOINT_SITES);
|
|
|
|
if (orgStats.AllocatedSharePointSiteCollections > -1
|
|
&& orgStats.CreatedSharePointSiteCollections >= orgStats.AllocatedSharePointSiteCollections)
|
|
{
|
|
return BusinessErrorCodes.ERROR_SHAREPOINT_RESOURCE_QUOTA_LIMIT;
|
|
}
|
|
|
|
// Check if stats resource is available
|
|
int serviceId = PackageController.GetPackageServiceId(item.PackageId, ResourceGroups.HostedSharePoint);
|
|
if (serviceId == 0)
|
|
{
|
|
return BusinessErrorCodes.ERROR_SHAREPOINT_RESOURCE_UNAVAILABLE;
|
|
}
|
|
|
|
StringDictionary hostedSharePointSettings = ServerController.GetServiceSettings(serviceId);
|
|
QuotaValueInfo quota = PackageController.GetPackageQuota(item.PackageId, Quotas.HOSTED_SHAREPOINT_USESHAREDSSL);
|
|
Uri rootWebApplicationUri = new Uri(hostedSharePointSettings["RootWebApplicationUri"]);
|
|
Organization org = OrganizationController.GetOrganization(item.OrganizationId);
|
|
string siteName = item.Name;
|
|
|
|
if (quota.QuotaAllocatedValue == 1)
|
|
{
|
|
string sslRoot = hostedSharePointSettings["SharedSSLRoot"];
|
|
|
|
|
|
string defaultDomain = org.DefaultDomain;
|
|
string hostNameBase = string.Empty;
|
|
|
|
string[] tmp = defaultDomain.Split('.');
|
|
if (tmp.Length == 2)
|
|
{
|
|
hostNameBase = tmp[0];
|
|
}
|
|
else
|
|
{
|
|
if (tmp.Length > 2)
|
|
{
|
|
hostNameBase = tmp[0] + tmp[1];
|
|
}
|
|
}
|
|
|
|
int counter = 0;
|
|
item.Name = String.Format("{0}://{1}", rootWebApplicationUri.Scheme, hostNameBase + "-" + counter.ToString() + "." + sslRoot);
|
|
siteName = String.Format("{0}", hostNameBase + "-" + counter.ToString() + "." + sslRoot);
|
|
|
|
while (DataProvider.CheckServiceItemExists(serviceId, item.Name, "WebsitePanel.Providers.SharePoint.SharePointSiteCollection, WebsitePanel.Providers.Base"))
|
|
{
|
|
counter++;
|
|
item.Name = String.Format("{0}://{1}", rootWebApplicationUri.Scheme, hostNameBase + "-" + counter.ToString() + "." + sslRoot);
|
|
siteName = String.Format("{0}", hostNameBase + "-" + counter.ToString() + "." + sslRoot);
|
|
}
|
|
}
|
|
else
|
|
item.Name = String.Format("{0}://{1}", rootWebApplicationUri.Scheme, item.Name);
|
|
|
|
if (rootWebApplicationUri.Port > 0 && rootWebApplicationUri.Port != 80 && rootWebApplicationUri.Port != 443)
|
|
{
|
|
item.PhysicalAddress = String.Format("{0}:{1}", item.Name, rootWebApplicationUri.Port);
|
|
}
|
|
else
|
|
{
|
|
item.PhysicalAddress = item.Name;
|
|
}
|
|
|
|
if (Utils.ParseBool(hostedSharePointSettings["LocalHostFile"], false))
|
|
{
|
|
item.RootWebApplicationInteralIpAddress = hostedSharePointSettings["RootWebApplicationInteralIpAddress"];
|
|
item.RootWebApplicationFQDN = item.Name.Replace(rootWebApplicationUri.Scheme + "://", "");
|
|
}
|
|
|
|
item.MaxSiteStorage = RecalculateMaxSize(org.MaxSharePointStorage, (int)item.MaxSiteStorage);
|
|
item.WarningStorage = item.MaxSiteStorage == -1 ? -1 : Math.Min((int)item.WarningStorage, item.MaxSiteStorage);
|
|
|
|
|
|
// Check package item with given name already exists.
|
|
if (PackageController.GetPackageItemByName(item.PackageId, item.Name, typeof(SharePointSiteCollection)) != null)
|
|
{
|
|
return BusinessErrorCodes.ERROR_SHAREPOINT_PACKAGE_ITEM_EXISTS;
|
|
}
|
|
|
|
// Log operation.
|
|
TaskManager.StartTask("HOSTEDSHAREPOINT", "ADD_SITE_COLLECTION", item.Name);
|
|
|
|
try
|
|
{
|
|
// Create site collection on server.
|
|
HostedSharePointServer hostedSharePointServer = GetHostedSharePointServer(serviceId);
|
|
|
|
hostedSharePointServer.CreateSiteCollection(item);
|
|
|
|
// Make record in metabase.
|
|
item.ServiceId = serviceId;
|
|
int itemId = PackageController.AddPackageItem(item);
|
|
|
|
hostedSharePointServer.SetPeoplePickerOu(item.Name, org.DistinguishedName);
|
|
|
|
int dnsServiceId = PackageController.GetPackageServiceId(item.PackageId, ResourceGroups.Dns);
|
|
if (dnsServiceId > 0)
|
|
{
|
|
string[] tmpStr = siteName.Split('.');
|
|
string hostName = tmpStr[0];
|
|
string domainName = siteName.Substring(hostName.Length + 1, siteName.Length - (hostName.Length + 1));
|
|
|
|
DomainInfo domain = ServerController.GetDomain(domainName);
|
|
if (domain != null)
|
|
{
|
|
string website = siteName;
|
|
|
|
DnsRecord[] records = ServerController.GetDnsZoneRecords(domain.DomainId);
|
|
foreach (DnsRecord record in records)
|
|
{
|
|
if (record.RecordType.Equals(DnsRecordType.A) && (record.RecordName == hostName))
|
|
{
|
|
ServerController.DeleteDnsZoneRecord(domain.DomainId, hostName, DnsRecordType.A, record.RecordData);
|
|
break;
|
|
}
|
|
}
|
|
|
|
ServerController.AddDnsZoneRecord(domain.DomainId, hostName, DnsRecordType.A, hostedSharePointSettings["RootWebApplicationIpAddress"], 0);
|
|
}
|
|
}
|
|
|
|
TaskManager.ItemId = itemId;
|
|
return itemId;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw TaskManager.WriteError(ex);
|
|
}
|
|
finally
|
|
{
|
|
TaskManager.CompleteTask();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deletes SharePoint site collection with given id.
|
|
/// </summary>
|
|
/// <param name="itemId">Site collection id within metabase.</param>
|
|
/// <returns>?</returns>
|
|
public static int DeleteSiteCollection(int itemId)
|
|
{
|
|
// Check account.
|
|
int accountCheck = SecurityContext.CheckAccount(DemandAccount.NotDemo | DemandAccount.IsActive);
|
|
if (accountCheck < 0)
|
|
{
|
|
return accountCheck;
|
|
}
|
|
|
|
// Load original meta item
|
|
SharePointSiteCollection origItem = (SharePointSiteCollection)PackageController.GetPackageItem(itemId);
|
|
if (origItem == null)
|
|
{
|
|
return BusinessErrorCodes.ERROR_SHAREPOINT_PACKAGE_ITEM_NOT_FOUND;
|
|
}
|
|
|
|
// Get service settings.
|
|
StringDictionary hostedSharePointSettings = ServerController.GetServiceSettings(origItem.ServiceId);
|
|
Uri rootWebApplicationUri = new Uri(hostedSharePointSettings["RootWebApplicationUri"]);
|
|
string siteName = origItem.Name.Replace(String.Format("{0}://", rootWebApplicationUri.Scheme), String.Empty);
|
|
|
|
// Log operation.
|
|
TaskManager.StartTask("HOSTEDSHAREPOINT", "DELETE_SITE", origItem.Name);
|
|
TaskManager.ItemId = itemId;
|
|
|
|
try
|
|
{
|
|
// Delete site collection on server.
|
|
HostedSharePointServer hostedSharePointServer = GetHostedSharePointServer(origItem.ServiceId);
|
|
hostedSharePointServer.DeleteSiteCollection(origItem);
|
|
// Delete record in metabase.
|
|
PackageController.DeletePackageItem(origItem.Id);
|
|
|
|
int dnsServiceId = PackageController.GetPackageServiceId(origItem.PackageId, ResourceGroups.Dns);
|
|
if (dnsServiceId > 0)
|
|
{
|
|
string[] tmpStr = siteName.Split('.');
|
|
string hostName = tmpStr[0];
|
|
string domainName = siteName.Substring(hostName.Length + 1, siteName.Length - (hostName.Length + 1));
|
|
|
|
DomainInfo domain = ServerController.GetDomain(domainName);
|
|
if (domain != null)
|
|
{
|
|
ServerController.DeleteDnsZoneRecord(domain.DomainId, hostName, DnsRecordType.A, hostedSharePointSettings["RootWebApplicationIpAddress"]);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw TaskManager.WriteError(ex);
|
|
}
|
|
finally
|
|
{
|
|
TaskManager.CompleteTask();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deletes SharePoint site collections which belong to organization.
|
|
/// </summary>
|
|
/// <param name="organizationId">Site collection id within metabase.</param>
|
|
public static void DeleteSiteCollections(int organizationId)
|
|
{
|
|
Organization org = OrganizationController.GetOrganization(organizationId);
|
|
SharePointSiteCollectionListPaged existentSiteCollections = GetSiteCollectionsPaged(org.PackageId, org.Id, String.Empty, String.Empty, String.Empty, 0, Int32.MaxValue);
|
|
foreach (SharePointSiteCollection existentSiteCollection in existentSiteCollections.SiteCollections)
|
|
{
|
|
DeleteSiteCollection(existentSiteCollection.Id);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Backups SharePoint site collection.
|
|
/// </summary>
|
|
/// <param name="itemId">Site collection id within metabase.</param>
|
|
/// <param name="fileName">Backed up site collection file name.</param>
|
|
/// <param name="zipBackup">A value which shows whether back up must be archived.</param>
|
|
/// <param name="download">A value which shows whether created back up must be downloaded.</param>
|
|
/// <param name="folderName">Local folder to store downloaded backup.</param>
|
|
/// <returns>Created backup file name. </returns>
|
|
public static string BackupSiteCollection(int itemId, string fileName, bool zipBackup, bool download, string folderName)
|
|
{
|
|
// Check account.
|
|
int accountCheck = SecurityContext.CheckAccount(DemandAccount.NotDemo | DemandAccount.IsActive);
|
|
if (accountCheck < 0)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
// Load original meta item
|
|
SharePointSiteCollection origItem = (SharePointSiteCollection)PackageController.GetPackageItem(itemId);
|
|
if (origItem == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
// Log operation.
|
|
TaskManager.StartTask("HOSTEDSHAREPOINT", "BACKUP_SITE_COLLECTION", origItem.Name);
|
|
TaskManager.ItemId = itemId;
|
|
|
|
try
|
|
{
|
|
// Create site collection on server.
|
|
HostedSharePointServer hostedSharePointServer = GetHostedSharePointServer(origItem.ServiceId);
|
|
string backFile = hostedSharePointServer.BackupSiteCollection(origItem.Name, fileName, zipBackup);
|
|
|
|
if (!download)
|
|
{
|
|
// Copy backup files to space folder.
|
|
string relFolderName = FilesController.CorrectRelativePath(folderName);
|
|
if (!relFolderName.EndsWith("\\"))
|
|
{
|
|
relFolderName = relFolderName + "\\";
|
|
}
|
|
|
|
// Create backup folder if not exists
|
|
if (!FilesController.DirectoryExists(origItem.PackageId, relFolderName))
|
|
{
|
|
FilesController.CreateFolder(origItem.PackageId, relFolderName);
|
|
}
|
|
|
|
string packageFile = relFolderName + Path.GetFileName(backFile);
|
|
|
|
// Delete destination file if exists
|
|
if (FilesController.FileExists(origItem.PackageId, packageFile))
|
|
{
|
|
FilesController.DeleteFiles(origItem.PackageId, new string[] { packageFile });
|
|
}
|
|
|
|
byte[] buffer = null;
|
|
|
|
int offset = 0;
|
|
do
|
|
{
|
|
// Read remote content.
|
|
buffer = hostedSharePointServer.GetTempFileBinaryChunk(backFile, offset, FILE_BUFFER_LENGTH);
|
|
|
|
// Write remote content.
|
|
FilesController.AppendFileBinaryChunk(origItem.PackageId, packageFile, buffer);
|
|
|
|
offset += FILE_BUFFER_LENGTH;
|
|
}
|
|
while (buffer.Length == FILE_BUFFER_LENGTH);
|
|
}
|
|
|
|
return backFile;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw TaskManager.WriteError(ex);
|
|
}
|
|
finally
|
|
{
|
|
TaskManager.CompleteTask();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Restores SharePoint site collection.
|
|
/// </summary>
|
|
/// <param name="itemId">Site collection id within metabase.</param>
|
|
/// <param name="uploadedFile"></param>
|
|
/// <param name="packageFile"></param>
|
|
/// <returns></returns>
|
|
public static int RestoreSiteCollection(int itemId, string uploadedFile, string packageFile)
|
|
{
|
|
// Check account.
|
|
int accountCheck = SecurityContext.CheckAccount(DemandAccount.NotDemo | DemandAccount.IsActive);
|
|
if (accountCheck < 0)
|
|
{
|
|
return accountCheck;
|
|
}
|
|
|
|
// Load original meta item.
|
|
SharePointSiteCollection origItem = (SharePointSiteCollection)PackageController.GetPackageItem(itemId);
|
|
if (origItem == null)
|
|
{
|
|
return BusinessErrorCodes.ERROR_SHAREPOINT_PACKAGE_ITEM_NOT_FOUND;
|
|
}
|
|
|
|
// Check package.
|
|
int packageCheck = SecurityContext.CheckPackage(origItem.PackageId, DemandPackage.IsActive);
|
|
if (packageCheck < 0)
|
|
{
|
|
return packageCheck;
|
|
}
|
|
|
|
// Log operation.
|
|
TaskManager.StartTask("HOSTEDSHAREPOINT", "BACKUP_SITE_COLLECTION", origItem.Name);
|
|
TaskManager.ItemId = itemId;
|
|
|
|
try
|
|
{
|
|
// Create site collection on server.
|
|
HostedSharePointServer hostedSharePointServer = GetHostedSharePointServer(origItem.ServiceId);
|
|
|
|
string backupFile = null;
|
|
if (!String.IsNullOrEmpty(packageFile))
|
|
{
|
|
// Copy package files to the remote SharePoint Server.
|
|
string path = null;
|
|
byte[] buffer = null;
|
|
|
|
int offset = 0;
|
|
do
|
|
{
|
|
// Read package file.
|
|
buffer = FilesController.GetFileBinaryChunk(origItem.PackageId, packageFile, offset, FILE_BUFFER_LENGTH);
|
|
|
|
// Write remote backup file
|
|
string tempPath = hostedSharePointServer.AppendTempFileBinaryChunk(Path.GetFileName(packageFile), path, buffer);
|
|
if (path == null)
|
|
{
|
|
path = tempPath;
|
|
backupFile = path;
|
|
}
|
|
|
|
offset += FILE_BUFFER_LENGTH;
|
|
}
|
|
while (buffer.Length == FILE_BUFFER_LENGTH);
|
|
}
|
|
else if (!String.IsNullOrEmpty(uploadedFile))
|
|
{
|
|
// Upladed files.
|
|
backupFile = uploadedFile;
|
|
}
|
|
|
|
// Restore.
|
|
if (!String.IsNullOrEmpty(backupFile))
|
|
{
|
|
hostedSharePointServer.RestoreSiteCollection(origItem, backupFile);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw TaskManager.WriteError(ex);
|
|
}
|
|
finally
|
|
{
|
|
TaskManager.CompleteTask();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets binary data chunk of specified size from specified offset.
|
|
/// </summary>
|
|
/// <param name="itemId">Item id to obtain realted service id.</param>
|
|
/// <param name="path">Path to file to get bunary data chunk from.</param>
|
|
/// <param name="offset">Offset from which to start data reading.</param>
|
|
/// <param name="length">Binary data chunk length.</param>
|
|
/// <returns>Binary data chunk read from file.</returns>
|
|
public static byte[] GetBackupBinaryChunk(int itemId, string path, int offset, int length)
|
|
{
|
|
// Load original meta item.
|
|
SharePointSiteCollection item = (SharePointSiteCollection)PackageController.GetPackageItem(itemId);
|
|
if (item == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
HostedSharePointServer hostedSharePointServer = GetHostedSharePointServer(item.ServiceId);
|
|
return hostedSharePointServer.GetTempFileBinaryChunk(path, offset, length);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Appends supplied binary data chunk to file.
|
|
/// </summary>
|
|
/// <param name="itemId">Item id to obtain realted service id.</param>
|
|
/// <param name="fileName">Non existent file name to append to.</param>
|
|
/// <param name="path">Full path to existent file to append to.</param>
|
|
/// <param name="chunk">Binary data chunk to append to.</param>
|
|
/// <returns>Path to file that was appended with chunk.</returns>
|
|
public static string AppendBackupBinaryChunk(int itemId, string fileName, string path, byte[] chunk)
|
|
{
|
|
// Load original meta item.
|
|
SharePointSiteCollection item = (SharePointSiteCollection)PackageController.GetPackageItem(itemId);
|
|
if (item == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
HostedSharePointServer hostedSharePointServer = GetHostedSharePointServer(item.ServiceId);
|
|
return hostedSharePointServer.AppendTempFileBinaryChunk(fileName, path, chunk);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes a new hosted SharePoint server proxy.
|
|
/// </summary>
|
|
/// <param name="serviceId">Hosted SharePoint service id.</param>
|
|
/// <returns>Hosted SharePoint server proxy.</returns>
|
|
private static HostedSharePointServer GetHostedSharePointServer(int serviceId)
|
|
{
|
|
|
|
HostedSharePointServer sps = new HostedSharePointServer();
|
|
ServiceProviderProxy.Init(sps, serviceId);
|
|
return sps;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets list of importable items.
|
|
/// </summary>
|
|
/// <param name="packageId">Package that owns importable items.</param>
|
|
/// <param name="itemTypeId">Item type id.</param>
|
|
/// <param name="itemType">Item type.</param>
|
|
/// <param name="group">Item resource group.</param>
|
|
/// <returns>List of importable item names.</returns>
|
|
public List<string> GetImportableItems(int packageId, int itemTypeId, Type itemType, ResourceGroupInfo group)
|
|
{
|
|
List<string> items = new List<string>();
|
|
|
|
// Get service id
|
|
int serviceId = PackageController.GetPackageServiceId(packageId, group.GroupName);
|
|
if (serviceId == 0)
|
|
{
|
|
return items;
|
|
}
|
|
|
|
HostedSharePointServer hostedSharePointServer = GetHostedSharePointServer(serviceId);
|
|
if (itemType == typeof(SharePointSiteCollection))
|
|
{
|
|
foreach (SharePointSiteCollection siteCollection in hostedSharePointServer.GetSiteCollections())
|
|
{
|
|
items.Add(siteCollection.Url);
|
|
}
|
|
}
|
|
|
|
return items;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Imports selected item into metabase.
|
|
/// </summary>
|
|
/// <param name="packageId">Package to which items must be imported.</param>
|
|
/// <param name="itemTypeId">Item type id.</param>
|
|
/// <param name="itemType">Item type.</param>
|
|
/// <param name="group">Item resource group.</param>
|
|
/// <param name="itemName">Item name to import.</param>
|
|
public void ImportItem(int packageId, int itemTypeId, Type itemType, ResourceGroupInfo group, string itemName)
|
|
{
|
|
// Get service id
|
|
int serviceId = PackageController.GetPackageServiceId(packageId, group.GroupName);
|
|
if (serviceId == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
HostedSharePointServer hostedSharePointServer = GetHostedSharePointServer(serviceId);
|
|
if (itemType == typeof(SharePointSiteCollection))
|
|
{
|
|
SharePointSiteCollection siteCollection = hostedSharePointServer.GetSiteCollection(itemName);
|
|
PackageController.AddPackageItem(siteCollection);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Backups service item by serializing it into supplied writer.
|
|
/// </summary>
|
|
/// <param name="tempFolder">Temporary directory path.</param>
|
|
/// <param name="writer">Xml wirter used to store backuped service provider items.</param>
|
|
/// <param name="item">Service provider item to be backed up..</param>
|
|
/// <param name="group">Service provider resource group.</param>
|
|
/// <returns>Resulting code.</returns>
|
|
public int BackupItem(string tempFolder, XmlWriter writer, ServiceProviderItem item, ResourceGroupInfo group)
|
|
{
|
|
SharePointSiteCollection siteCollection = item as SharePointSiteCollection;
|
|
if (siteCollection != null)
|
|
{
|
|
HostedSharePointServer hostedSharePointServer = GetHostedSharePointServer(siteCollection.ServiceId);
|
|
SharePointSiteCollection loadedSiteCollection = hostedSharePointServer.GetSiteCollection(siteCollection.Url);
|
|
// Update item
|
|
siteCollection.Url = loadedSiteCollection.Url;
|
|
siteCollection.OwnerLogin = loadedSiteCollection.OwnerLogin;
|
|
siteCollection.OwnerName = loadedSiteCollection.OwnerName;
|
|
siteCollection.OwnerEmail = loadedSiteCollection.OwnerEmail;
|
|
siteCollection.LocaleId = loadedSiteCollection.LocaleId;
|
|
siteCollection.Title = loadedSiteCollection.Title;
|
|
siteCollection.Description = loadedSiteCollection.Description;
|
|
// Serialize it.
|
|
XmlSerializer serializer = new XmlSerializer(typeof(SharePointSiteCollection));
|
|
serializer.Serialize(writer, siteCollection);
|
|
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Restore backed up previously service provider item.
|
|
/// </summary>
|
|
/// <param name="tempFolder">Temporary directory path.</param>
|
|
/// <param name="itemNode">Serialized service provider item.</param>
|
|
/// <param name="itemId">Service provider item id.</param>
|
|
/// <param name="itemType">Service provider item type.</param>
|
|
/// <param name="itemName">Service provider item name.</param>
|
|
/// <param name="packageId">Service provider item package.</param>
|
|
/// <param name="serviceId">Service provider item service id.</param>
|
|
/// <param name="group">Service provider item resource group.</param>
|
|
/// <returns>Resulting code.</returns>
|
|
public int RestoreItem(string tempFolder, XmlNode itemNode, int itemId, Type itemType, string itemName, int packageId, int serviceId, ResourceGroupInfo group)
|
|
{
|
|
if (itemType == typeof(SharePointSiteCollection))
|
|
{
|
|
HostedSharePointServer hostedSharePointServer = GetHostedSharePointServer(serviceId);
|
|
// Deserialize item.
|
|
XmlSerializer serializer = new XmlSerializer(typeof(SharePointSiteCollection));
|
|
SharePointSiteCollection siteCollection = (SharePointSiteCollection)serializer.Deserialize(new XmlNodeReader(itemNode.SelectSingleNode("SharePointSiteCollection")));
|
|
siteCollection.PackageId = packageId;
|
|
siteCollection.ServiceId = serviceId;
|
|
|
|
// Create site collection if needed.
|
|
if (hostedSharePointServer.GetSiteCollection(siteCollection.Url) == null)
|
|
{
|
|
hostedSharePointServer.CreateSiteCollection(siteCollection);
|
|
}
|
|
|
|
// Add metabase record if needed.
|
|
SharePointSiteCollection metaSiteCollection = (SharePointSiteCollection)PackageController.GetPackageItemByName(packageId, itemName, typeof(SharePointSiteCollection));
|
|
if (metaSiteCollection == null)
|
|
{
|
|
PackageController.AddPackageItem(siteCollection);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
private static int GetHostedSharePointServiceId(int packageId)
|
|
{
|
|
return PackageController.GetPackageServiceId(packageId, ResourceGroups.HostedSharePoint);
|
|
}
|
|
|
|
private static List<SharePointSiteCollection> GetOrganizationSharePointSiteCollections(int orgId)
|
|
{
|
|
Organization org = OrganizationController.GetOrganization(orgId);
|
|
|
|
SharePointSiteCollectionListPaged siteCollections = GetSiteCollectionsPaged(org.PackageId, org.Id, String.Empty, String.Empty, String.Empty, 0, Int32.MaxValue);
|
|
return siteCollections.SiteCollections;
|
|
}
|
|
|
|
private static int RecalculateStorageMaxSize(int size, int packageId)
|
|
{
|
|
PackageContext cntx = PackageController.GetPackageContext(packageId);
|
|
QuotaValueInfo quota = cntx.Quotas[Quotas.HOSTED_SHAREPOINT_STORAGE_SIZE];
|
|
|
|
if (quota.QuotaAllocatedValue == -1)
|
|
{
|
|
if (size == -1)//Unlimited
|
|
return -1;
|
|
else
|
|
return size;
|
|
}
|
|
else
|
|
{
|
|
if (size == -1)
|
|
return quota.QuotaAllocatedValue;
|
|
|
|
return Math.Min(size, quota.QuotaAllocatedValue);
|
|
}
|
|
}
|
|
|
|
private static int RecalculateMaxSize(int parentSize, int realSize)
|
|
{
|
|
if (parentSize == -1)
|
|
{
|
|
if (realSize == -1 || realSize == 0)
|
|
return -1;
|
|
else
|
|
return realSize;
|
|
}
|
|
|
|
|
|
if (realSize == -1 || realSize == 0)
|
|
return parentSize;
|
|
|
|
return Math.Min(parentSize, realSize);
|
|
|
|
}
|
|
|
|
|
|
public static int SetStorageSettings(int itemId, int maxStorage, int warningStorage, bool applyToSiteCollections)
|
|
{
|
|
// check account
|
|
int accountCheck = SecurityContext.CheckAccount(DemandAccount.NotDemo | DemandAccount.IsActive);
|
|
if (accountCheck < 0) return accountCheck;
|
|
|
|
// place log record
|
|
TaskManager.StartTask("HOSTED_SHAREPOINT", "SET_ORG_LIMITS");
|
|
TaskManager.ItemId = itemId;
|
|
|
|
try
|
|
{
|
|
Organization org = (Organization)PackageController.GetPackageItem(itemId);
|
|
if (org == null)
|
|
return 0;
|
|
|
|
// set limits
|
|
int realMaxSizeValue = RecalculateStorageMaxSize(maxStorage, org.PackageId);
|
|
|
|
org.MaxSharePointStorage = realMaxSizeValue;
|
|
|
|
org.WarningSharePointStorage = realMaxSizeValue == -1 ? -1 : Math.Min(warningStorage, realMaxSizeValue);
|
|
|
|
// save organization
|
|
UpdateOrganization(org);
|
|
|
|
if (applyToSiteCollections)
|
|
{
|
|
int serviceId = GetHostedSharePointServiceId(org.PackageId);
|
|
|
|
HostedSharePointServer hostedSharePointServer = GetHostedSharePointServer(serviceId);
|
|
|
|
List<SharePointSiteCollection> currentOrgSiteCollection =
|
|
GetOrganizationSharePointSiteCollections(org.Id);
|
|
|
|
|
|
foreach (SharePointSiteCollection siteCollection in currentOrgSiteCollection)
|
|
{
|
|
try
|
|
{
|
|
SharePointSiteCollection sc = GetSiteCollection(siteCollection.Id);
|
|
sc.MaxSiteStorage = realMaxSizeValue;
|
|
sc.WarningStorage = realMaxSizeValue == -1 ? -1 : warningStorage;
|
|
PackageController.UpdatePackageItem(sc);
|
|
|
|
hostedSharePointServer.UpdateQuotas(siteCollection.PhysicalAddress, realMaxSizeValue,
|
|
warningStorage);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
TaskManager.WriteError(ex);
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw TaskManager.WriteError(ex);
|
|
}
|
|
finally
|
|
{
|
|
TaskManager.CompleteTask();
|
|
}
|
|
}
|
|
|
|
public static SharePointSiteDiskSpace[] CalculateSharePointSitesDiskSpace(int itemId, out int errorCode)
|
|
{
|
|
SharePointSiteDiskSpace[] retDiskSpace = null;
|
|
errorCode = 0;
|
|
// check account
|
|
int accountCheck = SecurityContext.CheckAccount(DemandAccount.NotDemo | DemandAccount.IsActive);
|
|
if (accountCheck < 0)
|
|
{
|
|
errorCode = accountCheck;
|
|
return null;
|
|
}
|
|
|
|
// place log record
|
|
TaskManager.StartTask("HOSTED_SHAREPOINT", "CALCULATE_DISK_SPACE");
|
|
TaskManager.ItemId = itemId;
|
|
try
|
|
{
|
|
Organization org = (Organization)PackageController.GetPackageItem(itemId);
|
|
if (org == null)
|
|
return null;
|
|
|
|
int serviceId = GetHostedSharePointServiceId(org.PackageId);
|
|
|
|
HostedSharePointServer hostedSharePointServer = GetHostedSharePointServer(serviceId);
|
|
|
|
List<SharePointSiteCollection> currentOrgSiteCollection =
|
|
GetOrganizationSharePointSiteCollections(org.Id);
|
|
|
|
List<string> urls = new List<string>();
|
|
foreach (SharePointSiteCollection siteCollection in currentOrgSiteCollection)
|
|
{
|
|
urls.Add(siteCollection.PhysicalAddress);
|
|
}
|
|
if (urls.Count > 0)
|
|
retDiskSpace = hostedSharePointServer.CalculateSiteCollectionsDiskSpace(urls.ToArray());
|
|
else
|
|
{
|
|
retDiskSpace = new SharePointSiteDiskSpace[1];
|
|
retDiskSpace[0] = new SharePointSiteDiskSpace();
|
|
retDiskSpace[0].DiskSpace = 0;
|
|
retDiskSpace[0].Url = string.Empty;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw TaskManager.WriteError(ex);
|
|
}
|
|
finally
|
|
{
|
|
TaskManager.CompleteTask();
|
|
}
|
|
return retDiskSpace;
|
|
}
|
|
|
|
private static void UpdateOrganization(Organization organization)
|
|
{
|
|
PackageController.UpdatePackageItem(organization);
|
|
}
|
|
|
|
|
|
public static void UpdateQuota(int itemId, int siteCollectionId, int maxStorage, int warningStorage)
|
|
{
|
|
TaskManager.StartTask("HOSTED_SHAREPOINT", "UPDATE_QUOTA");
|
|
try
|
|
{
|
|
Organization org = (Organization)PackageController.GetPackageItem(itemId);
|
|
if (org == null)
|
|
return;
|
|
|
|
int serviceId = GetHostedSharePointServiceId(org.PackageId);
|
|
|
|
HostedSharePointServer hostedSharePointServer = GetHostedSharePointServer(serviceId);
|
|
|
|
SharePointSiteCollection sc = GetSiteCollection(siteCollectionId);
|
|
|
|
int maxSize = RecalculateMaxSize(org.MaxSharePointStorage, maxStorage);
|
|
int warningSize = warningStorage;
|
|
|
|
|
|
sc.MaxSiteStorage = maxSize;
|
|
sc.WarningStorage = maxSize == -1 ? -1 : Math.Min(warningSize, maxSize);
|
|
PackageController.UpdatePackageItem(sc);
|
|
|
|
hostedSharePointServer.UpdateQuotas(sc.PhysicalAddress, maxSize,
|
|
warningStorage);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw TaskManager.WriteError(ex);
|
|
}
|
|
finally
|
|
{
|
|
TaskManager.CompleteTask();
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Gets a value if caller is in demo mode.
|
|
/// </summary>
|
|
private static bool IsDemoMode
|
|
{
|
|
get
|
|
{
|
|
return (SecurityContext.CheckAccount(DemandAccount.NotDemo) < 0);
|
|
}
|
|
}
|
|
}
|
|
}
|