566 lines
24 KiB
C#
566 lines
24 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Web.UI.WebControls.WebParts;
|
|
using System.Xml;
|
|
using Microsoft.SharePoint;
|
|
using Microsoft.SharePoint.Deployment;
|
|
using Microsoft.SharePoint.Navigation;
|
|
using Microsoft.SharePoint.Publishing;
|
|
using Microsoft.SharePoint.Publishing.Navigation;
|
|
using Microsoft.SharePoint.WebPartPages;
|
|
using Taloyhtio.CondoUpdate.Common;
|
|
using WebPart = System.Web.UI.WebControls.WebParts.WebPart;
|
|
|
|
namespace CondoUpdate.AddDomusPage
|
|
{
|
|
public class UpdaterImpl : ICondoUpdater
|
|
{
|
|
public event EventHandler<LogEventArgs> OnNotify;
|
|
public void Update(object args)
|
|
{
|
|
string url = args as string;
|
|
if (string.IsNullOrEmpty(url))
|
|
{
|
|
this.warn("Url is empty");
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
this.updateImpl(url);
|
|
}
|
|
catch(Exception x)
|
|
{
|
|
this.error("Error occured during updating of Condo '{0}':\n{1}\n{2}", url, x.Message, x.StackTrace);
|
|
}
|
|
}
|
|
|
|
private void updateImpl(string url)
|
|
{
|
|
string sourceSiteUrl = "http://taloyhtio.mobimus.com/pirkanisannointikeskus/Kylmanojankatu4-8/";
|
|
string targetSiteUrl = url;
|
|
string pageName = "Tilintarkastus.aspx";
|
|
string fileToImport = "ExportedPage.cmp";
|
|
if (!this.import(sourceSiteUrl, targetSiteUrl, pageName, fileToImport))
|
|
{
|
|
this.warn("Import was not performed. Web site will be skipped");
|
|
return;
|
|
}
|
|
|
|
this.fixWebParts(url, pageName);
|
|
|
|
this.changeGlobalNavigation(url, pageName);
|
|
|
|
this.addPermissionsToPage(url, pageName);
|
|
}
|
|
|
|
private void changeGlobalNavigation(string url, string pageName)
|
|
{
|
|
using (var site = new SPSite(url))
|
|
{
|
|
using (var web = site.OpenWeb())
|
|
{
|
|
var pweb = PublishingWeb.GetPublishingWeb(web);
|
|
|
|
var globalNavigation = pweb.Navigation.GlobalNavigationNodes;
|
|
string title = pageName.Replace(".aspx", "");
|
|
var nodePage = globalNavigation.Cast<SPNavigationNode>().FirstOrDefault(n => n.Title == title);
|
|
if (nodePage != null)
|
|
{
|
|
this.warn("Navigation node already exists for page '{0}'", pageName);
|
|
return;
|
|
}
|
|
|
|
var page = pweb.GetPublishingPages().FirstOrDefault(p => string.Compare(p.Name, pageName, true) == 0);
|
|
if (page != null)
|
|
{
|
|
page.IncludeInGlobalNavigation = false;
|
|
page.IncludeInCurrentNavigation = false;
|
|
}
|
|
|
|
var node = createNode(title, page.Url, globalNavigation, "");
|
|
|
|
var nodeSite = globalNavigation.Cast<SPNavigationNode>().FirstOrDefault(n => n.Title == "Hallitukselle");
|
|
if (nodeSite != null)
|
|
{
|
|
node.Move(globalNavigation, nodeSite);
|
|
}
|
|
else
|
|
{
|
|
this.warn("Navigation node for Hallitukselle site not found for page '{0}'. Node position won't be changed", pageName);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private SPNavigationNode createNode(string targetTitle, string targetUrl, SPNavigationNodeCollection globalNavigation, string target)
|
|
{
|
|
var node = SPNavigationSiteMapNode.CreateSPNavigationNode(targetTitle, targetUrl,
|
|
NodeTypes.AuthoredLinkPlain, globalNavigation);
|
|
var dt = DateTime.Now;
|
|
node.Properties["CreatedDate"] = dt;
|
|
node.Properties["LastModifiedDate"] = dt;
|
|
node.Properties["Description"] = "";
|
|
node.Properties["Target"] = target;
|
|
node.Update();
|
|
return node;
|
|
}
|
|
|
|
private void addPermissionsToPage(string url, string pageName)
|
|
{
|
|
using (var site = new SPSite(url))
|
|
{
|
|
using (var web = site.OpenWeb())
|
|
{
|
|
var pweb = PublishingWeb.GetPublishingWeb(web);
|
|
|
|
var item = pweb.PagesList.Items.Cast<SPListItem>().FirstOrDefault(
|
|
i =>
|
|
{
|
|
return (i.File != null && string.Compare(i.File.Name, pageName, true) == 0);
|
|
});
|
|
if (item == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
string pmcGroupName = string.Format("{0} - Isännöitsijät", web.Site.RootWeb.Title);
|
|
if (SecurityHelper.IsGroupExist(web, pmcGroupName))
|
|
{
|
|
var group = SecurityHelper.GetSiteGroup(web, pmcGroupName);
|
|
var pmcRoleDefinition = web.RoleDefinitions.Cast<SPRoleDefinition>().FirstOrDefault(r => r.Name == "Isännöitsijä");
|
|
if (pmcRoleDefinition == null)
|
|
{
|
|
return;
|
|
}
|
|
var pmcRoleAssignment = new SPRoleAssignment(group);
|
|
SecurityHelper.AssignRoleToSecurableObject(web, item, pmcRoleDefinition, pmcRoleAssignment, false);
|
|
}
|
|
|
|
string hallitusGroupName = string.Format("{0} - Hallitus", web.Title);
|
|
if (SecurityHelper.IsGroupExist(web, hallitusGroupName))
|
|
{
|
|
var group = SecurityHelper.GetSiteGroup(web, hallitusGroupName);
|
|
SecurityHelper.AssignGroupRoleToSecurableObject(web, item, SPRoleType.Reader, group);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private bool import(string sourceSiteUrl, string targetSiteUrl, string pageName, string fileToImport)
|
|
{
|
|
using (var targetSite = new SPSite(targetSiteUrl))
|
|
{
|
|
using (var targetWeb = targetSite.OpenWeb())
|
|
{
|
|
var targetList = targetWeb.Lists.Cast<SPList>().FirstOrDefault(l => l.Title == "Sivut");
|
|
var item = targetList.Items.Cast<SPListItem>().FirstOrDefault(
|
|
i =>
|
|
{
|
|
return (i.File != null && string.Compare(i.File.Name, pageName, true) == 0);
|
|
});
|
|
if (item != null)
|
|
{
|
|
this.warn("Page '{0}' already exists on web '{1}'", pageName, targetWeb.Url);
|
|
return false;
|
|
}
|
|
|
|
|
|
using (var sourceSite = new SPSite(sourceSiteUrl))
|
|
{
|
|
using (var sourceWeb = sourceSite.OpenWeb())
|
|
{
|
|
var sourcePweb = PublishingWeb.GetPublishingWeb(sourceWeb);
|
|
var targetPweb = PublishingWeb.GetPublishingWeb(targetWeb);
|
|
|
|
return importImpl(targetWeb.Url,
|
|
sourcePweb.PagesList.RootFolder.ServerRelativeUrl,
|
|
targetPweb.PagesList.RootFolder.ServerRelativeUrl,
|
|
pageName,
|
|
fileToImport);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private bool importImpl(string fullTargetWebURL, string sourceItemParentUrl, string destinationItemParentUrl,
|
|
string pageName, string fileToImport)
|
|
{
|
|
if (!File.Exists(fileToImport))
|
|
{
|
|
this.error("File '{0}' not found", fileToImport);
|
|
return false;
|
|
}
|
|
|
|
var importSettings = new SPImportSettings();
|
|
importSettings.BaseFileName = fileToImport;
|
|
importSettings.FileLocation = Directory.GetCurrentDirectory();
|
|
importSettings.SiteUrl = fullTargetWebURL;
|
|
importSettings.RetainObjectIdentity = false;
|
|
importSettings.IncludeSecurity = SPIncludeSecurity.None;
|
|
importSettings.UpdateVersions = SPUpdateVersions.Append;
|
|
importSettings.UserInfoDateTime = SPImportUserInfoDateTimeOption.ImportAll;
|
|
importSettings.FileCompression = true;
|
|
importSettings.CommandLineVerbose = true;
|
|
importSettings.Validate();
|
|
var import =
|
|
new SPImport(importSettings);
|
|
bool importCompeted = false;
|
|
string importErrorMessage = "";
|
|
import.Started +=
|
|
(s, e) =>
|
|
{
|
|
if (e.RootObjects == null) return;
|
|
var rootObjects = e.RootObjects;
|
|
foreach (SPImportObject item in rootObjects)
|
|
{
|
|
this.info(" Check import object: SourceUrl = {0}, TargetParentUrl = {1}", item.SourceUrl, item.TargetParentUrl);
|
|
if (string.Compare(item.TargetParentUrl, sourceItemParentUrl + "/", true) == 0 ||
|
|
(item.SourceUrl.Contains("/" + pageName) && (item.Type == SPDeploymentObjectType.ListItem || item.Type == SPDeploymentObjectType.File)))
|
|
{
|
|
this.info(" Retarget item TargetParentUrl url from '{0}' to '{1}'", item.TargetParentUrl, destinationItemParentUrl + "/");
|
|
item.TargetParentUrl = destinationItemParentUrl + "/";
|
|
}
|
|
}
|
|
};
|
|
import.Error +=
|
|
(s, e) =>
|
|
{
|
|
importErrorMessage = e.ErrorMessage;
|
|
importCompeted = true;
|
|
};
|
|
import.Completed +=
|
|
(s, e) =>
|
|
{
|
|
importCompeted = true;
|
|
};
|
|
//Log.Comment("Starting import to URL {0}", siteURL);
|
|
importCompeted = false;//not thread safe but we dont need to be thread safe
|
|
importErrorMessage = null;
|
|
import.Run();
|
|
while (!importCompeted)
|
|
{
|
|
Thread.Sleep(1000);
|
|
}
|
|
if (importErrorMessage != null)
|
|
{
|
|
this.info("Problem occured during importing of " + sourceItemParentUrl + " and export file " +
|
|
fileToImport + " " + importErrorMessage);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private void fixWebParts(string url, string pageName)
|
|
{
|
|
using (var site = new SPSite(url))
|
|
{
|
|
using (var web = site.OpenWeb())
|
|
{
|
|
var pweb = PublishingWeb.GetPublishingWeb(web);
|
|
SPLimitedWebPartManager webPartManager = null;
|
|
try
|
|
{
|
|
//this.info("Get start page");
|
|
var item = pweb.PagesList.Items.Cast<SPListItem>().FirstOrDefault(
|
|
i =>
|
|
{
|
|
return (i.File != null && string.Compare(i.File.Name, pageName, true) == 0);
|
|
});
|
|
if (item == null)
|
|
{
|
|
this.error("Page '{0}' not found on web '{1}'", pageName, pweb.Url);
|
|
return;
|
|
}
|
|
var file = item.File;
|
|
if (file == null)
|
|
{
|
|
this.error("Page is null. Site won't be updated");
|
|
return;
|
|
}
|
|
|
|
if (file.CheckOutStatus == SPFile.SPCheckOutStatus.None)
|
|
{
|
|
//this.info("Checkout start page");
|
|
file.CheckOut();
|
|
}
|
|
else
|
|
{
|
|
// if file was checked out by another user, need undo check out and check in again in order to avoid errors
|
|
// when add web part
|
|
//this.info("Start page is already checked out. Undo previous check out and check out it again");
|
|
file.UndoCheckOut();
|
|
file.CheckOut();
|
|
}
|
|
|
|
//this.info("Get web part manager");
|
|
webPartManager = file.GetLimitedWebPartManager(PersonalizationScope.Shared);
|
|
if (webPartManager == null)
|
|
{
|
|
this.error("Web part manager is null. Site won't be updated");
|
|
file.UndoCheckOut();
|
|
return;
|
|
}
|
|
|
|
//this.info("Search for DataFormWebPart with title '{0}' on the start page", webPartTitle);
|
|
ContentEditorWebPart contentEditorWebPart = null;
|
|
PageViewerWebPart pageViewerWebPart = null;
|
|
var webParts = webPartManager.WebParts;
|
|
if (webParts != null)
|
|
{
|
|
foreach (WebPart wp in webParts)
|
|
{
|
|
if (wp.GetType().FullName == "Microsoft.SharePoint.WebPartPages.ContentEditorWebPart")
|
|
{
|
|
contentEditorWebPart = wp as ContentEditorWebPart;
|
|
}
|
|
else if (wp.GetType().FullName == "Microsoft.SharePoint.WebPartPages.PageViewerWebPart")
|
|
{
|
|
pageViewerWebPart = wp as PageViewerWebPart;
|
|
}
|
|
}
|
|
}
|
|
|
|
string oldPart = "/Kylmanojankatu4-8/";
|
|
string newPart = pweb.Url.Substring(pweb.Url.LastIndexOf("/")) + "/";
|
|
if (contentEditorWebPart != null)
|
|
{
|
|
var doc = new XmlDocument();
|
|
var el = doc.CreateElement("root");
|
|
el.InnerText = contentEditorWebPart.Content.InnerText.Replace(oldPart, newPart);
|
|
contentEditorWebPart.Content = el;
|
|
webPartManager.SaveChanges(contentEditorWebPart);
|
|
}
|
|
if (pageViewerWebPart != null)
|
|
{
|
|
pageViewerWebPart.ContentLink = pageViewerWebPart.ContentLink.Replace(oldPart, newPart);
|
|
webPartManager.SaveChanges(pageViewerWebPart);
|
|
}
|
|
|
|
//this.info("Checkin file");
|
|
file.Update();
|
|
file.CheckIn("Update web parts");
|
|
if (file.Item.ParentList.EnableMinorVersions)
|
|
{
|
|
file.Publish("Update web parts");
|
|
}
|
|
//this.info("Web part was sucessfully updated");
|
|
}
|
|
catch (Exception x)
|
|
{
|
|
this.error("Error occured when update web part on '{0}' site:\n{1}\n{2}", pweb.Web.Url,
|
|
x.Message, x.StackTrace);
|
|
var file = pweb.DefaultPage;
|
|
if (file.CheckOutStatus != SPFile.SPCheckOutStatus.None)
|
|
{
|
|
file.UndoCheckOut();
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
if (webPartManager != null)
|
|
{
|
|
if (webPartManager.Web != null)
|
|
{
|
|
webPartManager.Web.Dispose();
|
|
}
|
|
webPartManager.Dispose();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private void info(string msg, params object[] args)
|
|
{
|
|
this.notify(LogLevel.Info, msg, args);
|
|
}
|
|
|
|
private void warn(string msg, params object[] args)
|
|
{
|
|
this.notify(LogLevel.Warn, msg, args);
|
|
}
|
|
|
|
private void error(string msg, params object[] args)
|
|
{
|
|
this.notify(LogLevel.Error, msg, args);
|
|
}
|
|
|
|
private void notify(LogLevel level, string msg, params object[] args)
|
|
{
|
|
this.notify(level, string.Format(msg, args));
|
|
}
|
|
|
|
private void notify(LogLevel level, string msg)
|
|
{
|
|
if (this.OnNotify != null)
|
|
{
|
|
this.OnNotify(this, new LogEventArgs { LogLevel = level, Message = msg });
|
|
}
|
|
}
|
|
}
|
|
|
|
public static class SecurityHelper
|
|
{
|
|
public static void AddUserToGroup(SPWeb web, string loginName, string email, string name, string groupName)
|
|
{
|
|
// don't need to add user in group second time
|
|
if (IsUserInGroup(web, loginName, groupName))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!containsUser(web, loginName))
|
|
{
|
|
web.EnsureUser(loginName);
|
|
}
|
|
var group = web.SiteGroups[groupName];
|
|
group.AddUser(loginName, email, name, string.Empty);
|
|
}
|
|
|
|
public static void AddUserToGroup(SPWeb web, SPUser user, SPGroup group)
|
|
{
|
|
// don't need to add user in group second time
|
|
if (IsUserInGroup(web, user.LoginName, group.Name))
|
|
{
|
|
return;
|
|
}
|
|
|
|
group.AddUser(user);
|
|
}
|
|
|
|
public static bool IsUserInGroup(SPWeb web, string loginName, string groupName)
|
|
{
|
|
var group = web.SiteGroups[groupName];
|
|
return group.Users.Cast<SPUser>().Any(u => string.Compare(u.LoginName, loginName, true) == 0);
|
|
}
|
|
|
|
public static void CreateUser(SPWeb web, string loginName, string email, string name)
|
|
{
|
|
if (!containsUser(web, loginName))
|
|
{
|
|
try
|
|
{
|
|
var user = web.EnsureUser(loginName);
|
|
user.Email = email;
|
|
user.Update();
|
|
}
|
|
catch (SPException)
|
|
{
|
|
// EnsureUser can fail on one of WFEs because of some reason.
|
|
// To avoid this error add user manually
|
|
//string name = getUserName(loginName);
|
|
if (!string.IsNullOrEmpty(name))
|
|
{
|
|
web.AllUsers.Add(loginName, email, name, "");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static bool containsUser(SPWeb web, string loginName)
|
|
{
|
|
return web.AllUsers.Cast<SPUser>().Any(u => string.Compare(u.LoginName, loginName, true) == 0);
|
|
}
|
|
|
|
// private static string getUserName(string loginName)
|
|
// {
|
|
// if (string.IsNullOrEmpty(loginName))
|
|
// {
|
|
// return string.Empty;
|
|
// }
|
|
// if (loginName.Contains("\\"))
|
|
// {
|
|
// return string.Empty;
|
|
// }
|
|
// string name = loginName.Substring(loginName.LastIndexOf("\\"));
|
|
// return name;
|
|
// }
|
|
|
|
public static SPGroup EnsureSiteGroup(SPWeb web, string groupName)
|
|
{
|
|
if (!IsGroupExist(web, groupName))
|
|
{
|
|
web.SiteGroups.Add(groupName, web.SiteAdministrators[0], null, string.Empty);
|
|
}
|
|
|
|
return web.SiteGroups[groupName];
|
|
}
|
|
|
|
public static SPGroup GetSiteGroup(SPWeb web, string groupName)
|
|
{
|
|
return web.SiteGroups[groupName];
|
|
}
|
|
|
|
public static bool IsGroupExist(SPWeb web, string groupName)
|
|
{
|
|
return web.SiteGroups.Cast<SPGroup>().Any(g => string.Compare(g.Name, groupName, true) == 0);
|
|
}
|
|
|
|
public static void AssignGroupRoleToSecurableObject(SPWeb web, ISecurableObject securableObject,
|
|
SPRoleType roleType, SPGroup group)
|
|
{
|
|
SPRoleDefinition roleDefinition = web.RoleDefinitions.GetByType(roleType);
|
|
AssignGroupRoleToSecurableObject(web, securableObject, roleDefinition, group, false);
|
|
}
|
|
|
|
public static void AssignGroupRoleToSecurableObject(SPWeb web, ISecurableObject securableObject,
|
|
SPRoleType roleType, SPGroup group, bool copyRoleAssignment)
|
|
{
|
|
SPRoleDefinition roleDefinition = web.RoleDefinitions.GetByType(roleType);
|
|
AssignGroupRoleToSecurableObject(web, securableObject, roleDefinition, group, copyRoleAssignment);
|
|
}
|
|
|
|
public static void AssignGroupRoleToSecurableObject(SPWeb web, ISecurableObject securableObject,
|
|
SPRoleDefinition roleDefinition, SPGroup group, bool copyRoleAssignment)
|
|
{
|
|
SPRoleAssignment roleAssignment = new SPRoleAssignment(group);
|
|
AssignRoleToSecurableObject(web, securableObject, roleDefinition, roleAssignment, copyRoleAssignment);
|
|
}
|
|
|
|
public static void AssignGroupRoleToSecurableObject(SPWeb web, ISecurableObject securableObject,
|
|
SPRoleDefinition roleDefinition, SPGroup group)
|
|
{
|
|
SPRoleAssignment roleAssignment = new SPRoleAssignment(group);
|
|
AssignRoleToSecurableObject(web, securableObject, roleDefinition, roleAssignment, true);
|
|
}
|
|
|
|
public static void AssignUserRoleToSecurableObject(SPWeb web, ISecurableObject securableObject,
|
|
SPRoleType roleType, SPUser user)
|
|
{
|
|
SPRoleAssignment roleAssignment = new SPRoleAssignment(user);
|
|
SPRoleDefinition roleDefinition = web.RoleDefinitions.GetByType(roleType);
|
|
AssignRoleToSecurableObject(web, securableObject, roleDefinition, roleAssignment, true);
|
|
}
|
|
|
|
public static void AssignRoleToSecurableObject(SPWeb web, ISecurableObject securableObject, SPRoleDefinition roleDefinition, SPRoleAssignment roleAssignment,
|
|
bool copyRoleAssignment)
|
|
{
|
|
roleAssignment.RoleDefinitionBindings.Add(roleDefinition);
|
|
if (!securableObject.HasUniqueRoleAssignments)
|
|
{
|
|
securableObject.BreakRoleInheritance(copyRoleAssignment);
|
|
// 2013-01-22 apetuhov: BreakRoleInheritance causes reset of AllowUnsafeUpdates to false.
|
|
// See http://hristopavlov.wordpress.com/2008/05/16/what-you-need-to-know-about-allowunsafeupdates/
|
|
if (web != null && !web.AllowUnsafeUpdates)
|
|
{
|
|
web.AllowUnsafeUpdates = true;
|
|
}
|
|
if (securableObject is SPWeb)
|
|
{
|
|
var secureWeb = securableObject as SPWeb;
|
|
if (!secureWeb.AllowUnsafeUpdates)
|
|
{
|
|
secureWeb.AllowUnsafeUpdates = true;
|
|
}
|
|
}
|
|
}
|
|
securableObject.RoleAssignments.Add(roleAssignment);
|
|
}
|
|
}
|
|
}
|