Files
Umbraco-CMS/src/Umbraco.Web/WebServices/DomainsApiController.cs

192 lines
7.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Web.Http;
using System.Web.Services.Description;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Web.Routing;
using Umbraco.Web.WebApi;
//using umbraco.cms.businesslogic.language;
using umbraco.BusinessLogic.Actions;
using umbraco.cms.businesslogic.web;
using Umbraco.Web.WebApi.Filters;
namespace Umbraco.Web.WebServices
{
/// <summary>
/// A REST controller used for managing domains.
/// </summary>
/// <remarks>Nothing to do with Active Directory.</remarks>
[ValidateAngularAntiForgeryToken]
public class DomainsApiController : UmbracoAuthorizedApiController
{
[HttpPost]
// can't pass multiple complex args in json post request...
public PostBackModel SaveLanguageAndDomains(PostBackModel model)
{
var node = ApplicationContext.Current.Services.ContentService.GetById(model.NodeId);
if (node == null)
{
var response = Request.CreateResponse(HttpStatusCode.BadRequest);
response.Content = new StringContent(string.Format("There is no content node with id {0}.", model.NodeId));
response.ReasonPhrase = "Node Not Found.";
throw new HttpResponseException(response);
}
if (UmbracoUser.GetPermissions(node.Path).Contains(ActionAssignDomain.Instance.Letter) == false)
{
var response = Request.CreateResponse(HttpStatusCode.BadRequest);
response.Content = new StringContent("You do not have permission to assign domains on that node.");
response.ReasonPhrase = "Permission Denied.";
throw new HttpResponseException(response);
}
model.Valid = true;
var domains = Services.DomainService.GetAssignedDomains(model.NodeId, true).ToArray();
var languages = Services.LocalizationService.GetAllLanguages().ToArray();
var language = model.Language > 0 ? languages.FirstOrDefault(l => l.Id == model.Language) : null;
// process wildcard
if (language != null)
{
// yet there is a race condition here...
var wildcard = domains.FirstOrDefault(d => d.IsWildcard);
if (wildcard != null)
{
wildcard.LanguageId = language.Id;
}
else
{
wildcard = new UmbracoDomain("*" + model.NodeId)
{
LanguageId = model.Language,
RootContentId = model.NodeId
};
}
var saveAttempt = Services.DomainService.Save(wildcard);
if (saveAttempt == false)
{
var response = Request.CreateResponse(HttpStatusCode.BadRequest);
response.Content = new StringContent("Saving domain failed");
response.ReasonPhrase = saveAttempt.Result.StatusType.ToString();
throw new HttpResponseException(response);
}
}
else
{
var wildcard = domains.FirstOrDefault(d => d.IsWildcard);
if (wildcard != null)
{
Services.DomainService.Delete(wildcard);
}
}
// process domains
// delete every (non-wildcard) domain, that exists in the DB yet is not in the model
foreach (var domain in domains.Where(d => d.IsWildcard == false && model.Domains.All(m => m.Name.InvariantEquals(d.DomainName) == false)))
{
Services.DomainService.Delete(domain);
}
var names = new List<string>();
// create or update domains in the model
foreach (var domainModel in model.Domains.Where(m => string.IsNullOrWhiteSpace(m.Name) == false))
{
language = languages.FirstOrDefault(l => l.Id == domainModel.Lang);
if (language == null)
continue;
var name = domainModel.Name.ToLowerInvariant();
if (names.Contains(name))
{
domainModel.Duplicate = true;
continue;
}
names.Add(name);
var domain = domains.FirstOrDefault(d => d.DomainName.InvariantEquals(domainModel.Name));
if (domain != null)
{
domain.LanguageId = language.Id;
Services.DomainService.Save(domain);
}
else if (Services.DomainService.Exists(domainModel.Name))
{
domainModel.Duplicate = true;
var xdomain = Services.DomainService.GetByName(domainModel.Name);
var xrcid = xdomain.RootContentId;
if (xrcid.HasValue)
{
var xcontent = Services.ContentService.GetById(xrcid.Value);
var xnames = new List<string>();
while (xcontent != null)
{
xnames.Add(xcontent.Name);
if (xcontent.ParentId < -1)
xnames.Add("Recycle Bin");
xcontent = xcontent.Parent();
}
xnames.Reverse();
domainModel.Other = "/" + string.Join("/", xnames);
}
}
else
{
// yet there is a race condition here...
var newDomain = new UmbracoDomain(name)
{
LanguageId = domainModel.Lang,
RootContentId = model.NodeId
};
var saveAttempt = Services.DomainService.Save(newDomain);
if (saveAttempt == false)
{
var response = Request.CreateResponse(HttpStatusCode.BadRequest);
response.Content = new StringContent("Saving new domain failed");
response.ReasonPhrase = saveAttempt.Result.StatusType.ToString();
throw new HttpResponseException(response);
}
}
}
model.Valid = model.Domains.All(m => m.Duplicate == false);
return model;
}
#region Models
public class PostBackModel
{
public bool Valid { get; set; }
public int NodeId { get; set; }
public int Language { get; set; }
public DomainModel[] Domains { get; set; }
}
public class DomainModel
{
public DomainModel(string name, int lang)
{
Name = name;
Lang = lang;
}
public string Name { get; private set; }
public int Lang { get; private set; }
public bool Duplicate { get; set; }
public string Other { get; set; }
}
#endregion
}
}