Web.Routing - hide new wildcard domains from public APIs
only way to get them is through internal methods + improve / fix domains handling + fix failing tests
This commit is contained in:
@@ -25,7 +25,7 @@ namespace Umbraco.Tests.Routing
|
||||
|
||||
void InitializeLanguagesAndDomains()
|
||||
{
|
||||
var domains = Domain.GetDomains();
|
||||
var domains = Domain.GetDomains(true); // we want wildcards too here
|
||||
foreach (var d in domains)
|
||||
d.Delete();
|
||||
|
||||
|
||||
@@ -26,6 +26,10 @@ namespace Umbraco.Tests.Routing
|
||||
true);
|
||||
|
||||
SettingsForTests.SettingsFilePath = Core.IO.IOHelper.MapPath(Core.IO.SystemDirectories.Config + Path.DirectorySeparatorChar, false);
|
||||
|
||||
SiteDomainHelperResolver.Reset();
|
||||
SiteDomainHelperResolver.Current = new SiteDomainHelperResolver(new SiteDomainHelper());
|
||||
FreezeResolution();
|
||||
}
|
||||
|
||||
internal override IRoutesCache GetRoutesCache()
|
||||
|
||||
@@ -20,6 +20,10 @@ namespace Umbraco.Tests.Routing
|
||||
|
||||
// ensure we can create them although the content is not in the database
|
||||
TestHelper.DropForeignKeys("umbracoDomains");
|
||||
|
||||
SiteDomainHelperResolver.Reset();
|
||||
SiteDomainHelperResolver.Current = new SiteDomainHelperResolver(new SiteDomainHelper());
|
||||
FreezeResolution();
|
||||
}
|
||||
|
||||
internal override IRoutesCache GetRoutesCache()
|
||||
@@ -370,7 +374,7 @@ namespace Umbraco.Tests.Routing
|
||||
[Test]
|
||||
public void Get_Nice_Url_Alternate()
|
||||
{
|
||||
var routingContext = GetRoutingContext("http://domain1.com/test", 1111);
|
||||
var routingContext = GetRoutingContext("http://domain1.com/en/test", 1111);
|
||||
|
||||
SettingsForTests.UseDirectoryUrls = true;
|
||||
SettingsForTests.HideTopLevelNodeFromPath = false;
|
||||
@@ -378,13 +382,12 @@ namespace Umbraco.Tests.Routing
|
||||
InitializeLanguagesAndDomains();
|
||||
SetDomains5();
|
||||
|
||||
var result = routingContext.UrlProvider.GetOtherUrls(100111);
|
||||
var url = routingContext.UrlProvider.GetUrl(100111, true);
|
||||
Assert.AreEqual("http://domain1.com/en/1001-1-1/", url);
|
||||
|
||||
var result = routingContext.UrlProvider.GetOtherUrls(100111).ToArray();
|
||||
|
||||
// will always get absolute urls
|
||||
// all of them
|
||||
// including the local one - duplicate?! - then must manually exclude?
|
||||
Assert.AreEqual(3, result.Count());
|
||||
Assert.IsTrue(result.Contains("http://domain1.com/en/1001-1-1/"));
|
||||
Assert.AreEqual(2, result.Count());
|
||||
Assert.IsTrue(result.Contains("http://domain1a.com/en/1001-1-1/"));
|
||||
Assert.IsTrue(result.Contains("http://domain1b.com/en/1001-1-1/"));
|
||||
}
|
||||
|
||||
@@ -69,6 +69,10 @@ namespace Umbraco.Tests.Routing
|
||||
|
||||
// ensure we can create them although the content is not in the database
|
||||
TestHelper.DropForeignKeys("umbracoDomains");
|
||||
|
||||
SiteDomainHelperResolver.Reset();
|
||||
SiteDomainHelperResolver.Current = new SiteDomainHelperResolver(new SiteDomainHelper());
|
||||
FreezeResolution();
|
||||
}
|
||||
|
||||
internal override IRoutesCache GetRoutesCache()
|
||||
|
||||
@@ -95,7 +95,7 @@ namespace Umbraco.Web.Routing
|
||||
LogHelper.Debug<ContentFinderByNiceUrl>("Query matches, id={0}", () => docreq.PublishedContent.Id);
|
||||
|
||||
var rootNodeId = docreq.Domain == null ? (int?) null : docreq.Domain.RootNodeId;
|
||||
var iscanon = _doDomainLookup && !DomainHelper.ExistsDomainInPath(DomainHelper.GetAllDomains(), node.Path, rootNodeId);
|
||||
var iscanon = _doDomainLookup && !DomainHelper.ExistsDomainInPath(DomainHelper.GetAllDomains(false), node.Path, rootNodeId);
|
||||
if (!iscanon)
|
||||
LogHelper.Debug<ContentFinderByNiceUrl>("Non canonical url");
|
||||
|
||||
|
||||
@@ -17,22 +17,24 @@ namespace Umbraco.Web.Routing
|
||||
/// <summary>
|
||||
/// Gets all domains defined in the system.
|
||||
/// </summary>
|
||||
/// <param name="includeWildcards">A value indicating whether to include wildcard domains.</param>
|
||||
/// <returns>All domains defined in the system.</returns>
|
||||
/// <remarks>This is to temporarily abstract Umbraco's API.</remarks>
|
||||
internal static Domain[] GetAllDomains()
|
||||
internal static Domain[] GetAllDomains(bool includeWildcards)
|
||||
{
|
||||
return Domain.GetDomains().ToArray();
|
||||
return Domain.GetDomains(includeWildcards).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all domains defined in the system at a specified node.
|
||||
/// </summary>
|
||||
/// <param name="nodeId">The node identifier.</param>
|
||||
/// <param name="includeWildcards">A value indicating whether to include wildcard domains.</param>
|
||||
/// <returns>All domains defined in the system at the specified node.</returns>
|
||||
/// <remarks>This is to temporarily abstract Umbraco's API.</remarks>
|
||||
internal static Domain[] GetNodeDomains(int nodeId)
|
||||
internal static Domain[] GetNodeDomains(int nodeId, bool includeWildcards)
|
||||
{
|
||||
return Domain.GetDomainsById(nodeId);
|
||||
return Domain.GetDomains(includeWildcards).Where(d => d.RootNodeId == nodeId).ToArray();
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -44,7 +46,9 @@ namespace Umbraco.Web.Routing
|
||||
/// </summary>
|
||||
/// <param name="nodeId">The node identifier.</param>
|
||||
/// <param name="current">The uri, or null.</param>
|
||||
/// <returns>The domain and its uri, if any, that best matches the specified uri.</returns>
|
||||
/// <returns>The domain and its uri, if any, that best matches the specified uri, else null.</returns>
|
||||
/// <remarks>If at least a domain is set on the node then the method returns the domain that
|
||||
/// best matches the specified uri, else it returns null.</remarks>
|
||||
internal static DomainAndUri DomainForNode(int nodeId, Uri current)
|
||||
{
|
||||
// be safe
|
||||
@@ -52,13 +56,19 @@ namespace Umbraco.Web.Routing
|
||||
return null;
|
||||
|
||||
// get the domains on that node
|
||||
var domains = GetNodeDomains(nodeId);
|
||||
var domains = GetNodeDomains(nodeId, false);
|
||||
|
||||
// filter those that match
|
||||
// none?
|
||||
if (!domains.Any())
|
||||
return null;
|
||||
|
||||
// else filter
|
||||
var helper = SiteDomainHelperResolver.Current.Helper;
|
||||
var domainAndUri = DomainForUri(domains, current, domainAndUris => helper.MapDomain(current, domainAndUris));
|
||||
|
||||
// return null or the uri
|
||||
if (domainAndUri == null)
|
||||
throw new Exception("DomainForUri returned null.");
|
||||
|
||||
return domainAndUri;
|
||||
}
|
||||
|
||||
@@ -67,7 +77,9 @@ namespace Umbraco.Web.Routing
|
||||
/// </summary>
|
||||
/// <param name="nodeId">The node identifier.</param>
|
||||
/// <param name="current">The uri, or null.</param>
|
||||
/// <returns>The domains and their uris, that match the specified uri.</returns>
|
||||
/// <returns>The domains and their uris, that match the specified uri, else null.</returns>
|
||||
/// <remarks>If at least a domain is set on the node then the method returns the domains that
|
||||
/// best match the specified uri, else it returns null.</remarks>
|
||||
internal static IEnumerable<DomainAndUri> DomainsForNode(int nodeId, Uri current)
|
||||
{
|
||||
// be safe
|
||||
@@ -75,15 +87,18 @@ namespace Umbraco.Web.Routing
|
||||
return null;
|
||||
|
||||
// get the domains on that node
|
||||
var domains = GetNodeDomains(nodeId);
|
||||
var domains = GetNodeDomains(nodeId, false);
|
||||
|
||||
// filter those that match
|
||||
// none?
|
||||
if (!domains.Any())
|
||||
return null;
|
||||
|
||||
// get the domains and their uris
|
||||
var domainAndUris = DomainsForUri(domains, current).ToArray();
|
||||
|
||||
// return null or a (maybe empty) enumerable of uris
|
||||
// filter
|
||||
var helper = SiteDomainHelperResolver.Current.Helper;
|
||||
var domainAndUris2 = helper.MapDomains(current, domainAndUris).ToArray();
|
||||
return domainAndUris2.Any() ? domainAndUris2 : null;
|
||||
return helper.MapDomains(current, domainAndUris).ToArray();
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -121,17 +136,16 @@ namespace Umbraco.Web.Routing
|
||||
DomainAndUri domainAndUri;
|
||||
if (current == null)
|
||||
{
|
||||
// take the first one by default (is that OK?)
|
||||
domainAndUri = domainsAndUris.First();
|
||||
// take the first one by default (what else can we do?)
|
||||
domainAndUri = domainsAndUris.First(); // .First() protected by .Any() above
|
||||
}
|
||||
else
|
||||
{
|
||||
// look for a domain that would be the base of the hint
|
||||
// assume only one can match the hint (is that OK?)
|
||||
// look for the first domain that would be the base of the hint
|
||||
var hintWithSlash = current.EndPathWithSlash();
|
||||
domainAndUri = domainsAndUris
|
||||
.FirstOrDefault(d => d.Uri.EndPathWithSlash().IsBaseOf(hintWithSlash));
|
||||
// if none matches, then try to run the filter to sort them out
|
||||
// if none matches, then try to run the filter to pick a domain
|
||||
if (domainAndUri == null && filter != null)
|
||||
{
|
||||
domainAndUri = filter(domainsAndUris);
|
||||
|
||||
@@ -166,7 +166,7 @@ namespace Umbraco.Web.Routing
|
||||
LogHelper.Debug<PublishedContentRequestEngine>("{0}Uri=\"{1}\"", () => tracePrefix, () => _pcr.Uri);
|
||||
|
||||
// try to find a domain matching the current request
|
||||
var domainAndUri = DomainHelper.DomainForUri(Domain.GetDomains().ToArray(), _pcr.Uri);
|
||||
var domainAndUri = DomainHelper.DomainForUri(DomainHelper.GetAllDomains(false), _pcr.Uri);
|
||||
|
||||
// handle domain
|
||||
if (domainAndUri != null)
|
||||
@@ -216,7 +216,7 @@ namespace Umbraco.Web.Routing
|
||||
var nodePath = _pcr.PublishedContent.Path;
|
||||
LogHelper.Debug<PublishedContentRequestEngine>("{0}Path=\"{1}\"", () => tracePrefix, () => nodePath);
|
||||
var rootNodeId = _pcr.HasDomain ? _pcr.Domain.RootNodeId : (int?)null;
|
||||
var domain = DomainHelper.FindWildcardDomainInPath(Domain.GetDomains().ToArray(), nodePath, rootNodeId);
|
||||
var domain = DomainHelper.FindWildcardDomainInPath(DomainHelper.GetAllDomains(true), nodePath, rootNodeId);
|
||||
|
||||
if (domain != null)
|
||||
{
|
||||
|
||||
@@ -208,15 +208,23 @@ namespace Umbraco.Web.Routing
|
||||
IEnumerable<DomainAndUri> ret;
|
||||
|
||||
using (ConfigReadLock) // so nothing changes between GetQualifiedSites and access to bindings
|
||||
{
|
||||
{
|
||||
var qualifiedSites = GetQualifiedSitesInsideLock(current);
|
||||
|
||||
// exclude the current one (avoid producing the absolute equivalent of what GetUrl returns)
|
||||
ret = domainAndUris.Where(d => d.Uri.GetLeftPart(UriPartial.Authority) != currentAuthority);
|
||||
var hintWithSlash = current.EndPathWithSlash();
|
||||
var hinted = domainAndUris.FirstOrDefault(d => d.Uri.EndPathWithSlash().IsBaseOf(hintWithSlash));
|
||||
ret = hinted == null ? domainAndUris : domainAndUris.Where(d => d != hinted);
|
||||
|
||||
// exclude the default one (avoid producing a possible duplicate of what GetUrl returns)
|
||||
var mainDomain = MapDomain(domainAndUris, qualifiedSites, currentAuthority); // what GetUrl would get
|
||||
ret = ret.Where(d => d != mainDomain);
|
||||
// only if the default one cannot be the current one ie if hinted is not null
|
||||
if (hinted == null && domainAndUris.Any())
|
||||
{
|
||||
// it is illegal to call MapDomain if domainAndUris is empty
|
||||
// also, domainAndUris should NOT contain current, hence the test on hinted
|
||||
var mainDomain = MapDomain(domainAndUris, qualifiedSites, currentAuthority); // what GetUrl would get
|
||||
ret = ret.Where(d => d != mainDomain);
|
||||
}
|
||||
|
||||
// we do our best, but can't do the impossible
|
||||
if (qualifiedSites == null)
|
||||
@@ -280,6 +288,11 @@ namespace Umbraco.Web.Routing
|
||||
|
||||
private static DomainAndUri MapDomain(DomainAndUri[] domainAndUris, Dictionary<string, string[]> qualifiedSites, string currentAuthority)
|
||||
{
|
||||
if (domainAndUris == null)
|
||||
throw new ArgumentNullException("domainAndUris");
|
||||
if (!domainAndUris.Any())
|
||||
throw new ArgumentException("Cannot be empty.", "domainAndUris");
|
||||
|
||||
// we do our best, but can't do the impossible
|
||||
if (qualifiedSites == null)
|
||||
return domainAndUris.First();
|
||||
|
||||
@@ -17,29 +17,6 @@ namespace Umbraco.Web.WebServices
|
||||
/// <remarks>Nothing to do with Active Directory.</remarks>
|
||||
public class DomainsApiController : UmbracoAuthorizedApiController
|
||||
{
|
||||
[HttpGet]
|
||||
public DomainModel[] ListDomains(int nodeId)
|
||||
{
|
||||
var node = ApplicationContext.Current.Services.ContentService.GetById(nodeId);
|
||||
|
||||
if (node == null)
|
||||
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.BadRequest)
|
||||
{
|
||||
Content = new StringContent(string.Format("There is no content node with id {0}.", nodeId)),
|
||||
ReasonPhrase = "Node Not Found."
|
||||
});
|
||||
|
||||
if (!UmbracoUser.GetPermissions(node.Path).Contains(global::umbraco.BusinessLogic.Actions.ActionAssignDomain.Instance.Letter))
|
||||
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.Unauthorized)
|
||||
{
|
||||
Content = new StringContent("You do not have permission to assign domains on that node."),
|
||||
ReasonPhrase = "Permission Denied."
|
||||
});
|
||||
|
||||
var domains = Routing.DomainHelper.GetNodeDomains(nodeId);
|
||||
return domains.Select(d => new DomainModel(d.Name, d.Language.id)).ToArray();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
// can't pass multiple complex args in json post request...
|
||||
public PostBackModel SaveLanguageAndDomains(PostBackModel model)
|
||||
@@ -61,7 +38,7 @@ namespace Umbraco.Web.WebServices
|
||||
});
|
||||
|
||||
model.Valid = true;
|
||||
var domains = Routing.DomainHelper.GetNodeDomains(model.NodeId);
|
||||
var domains = Routing.DomainHelper.GetNodeDomains(model.NodeId, true);
|
||||
var languages = global::umbraco.cms.businesslogic.language.Language.GetAllAsList().ToArray();
|
||||
var language = model.Language > 0 ? languages.FirstOrDefault(l => l.id == model.Language) : null;
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace umbraco.dialogs
|
||||
pane_domains.Text = ui.Text("assignDomain", "setDomains");
|
||||
prop_language.Text = ui.Text("assignDomain", "language");
|
||||
|
||||
var nodeDomains = DomainHelper.GetNodeDomains(nodeId);
|
||||
var nodeDomains = DomainHelper.GetNodeDomains(nodeId, true);
|
||||
var wildcard = nodeDomains.FirstOrDefault(d => d.IsWildcard);
|
||||
|
||||
var sb = new StringBuilder();
|
||||
|
||||
@@ -147,7 +147,12 @@ namespace umbraco.cms.businesslogic.web
|
||||
|
||||
internal static List<Domain> GetDomains()
|
||||
{
|
||||
return Cache.GetCacheItem<List<Domain>>("UmbracoDomainList", getDomainsSyncLock, TimeSpan.FromMinutes(30),
|
||||
return GetDomains(false);
|
||||
}
|
||||
|
||||
internal static List<Domain> GetDomains(bool includeWildcards)
|
||||
{
|
||||
var domains = Cache.GetCacheItem<List<Domain>>("UmbracoDomainList", getDomainsSyncLock, TimeSpan.FromMinutes(30),
|
||||
delegate
|
||||
{
|
||||
List<Domain> result = new List<Domain>();
|
||||
@@ -170,6 +175,11 @@ namespace umbraco.cms.businesslogic.web
|
||||
}
|
||||
return result;
|
||||
});
|
||||
|
||||
if (!includeWildcards)
|
||||
domains = domains.Where(d => !d.IsWildcard).ToList();
|
||||
|
||||
return domains;
|
||||
}
|
||||
|
||||
public static Domain GetDomain(string DomainName)
|
||||
|
||||
Reference in New Issue
Block a user