IDN support: new validation of domain names, make DNS providers use ascii and iis unicode. Block use of IDN domain names in organizations and mail

This commit is contained in:
Olov Karlsson 2014-12-19 23:27:15 +01:00
parent a211800357
commit 2d96231e35
24 changed files with 581 additions and 203 deletions

View file

@ -21064,6 +21064,7 @@ SET @sql = @sql + ' SELECT COUNT(DomainID) FROM @Domains;SELECT
WS.ItemName AS WebSiteName,
ISNULL(MD.ItemID, 0) AS MailDomainID,
MD.ItemName AS MailDomainName,
Z.ItemName AS ZoneName,
D.IsSubDomain,
D.IsInstantAlias,
D.IsDomainPointer,

View file

@ -6057,6 +6057,112 @@ END
RETURN
GO
-- wsp-10053: IDN, return ZoneName also from GetDomainsPaged (already exists in other GetDomain-sps)
ALTER PROCEDURE [dbo].[GetDomainsPaged]
(
@ActorID int,
@PackageID int,
@ServerID int,
@Recursive bit,
@FilterColumn nvarchar(50) = '',
@FilterValue nvarchar(50) = '',
@SortColumn nvarchar(50),
@StartRow int,
@MaximumRows int
)
AS
SET NOCOUNT ON
-- check rights
IF dbo.CheckActorPackageRights(@ActorID, @PackageID) = 0
RAISERROR('You are not allowed to access this package', 16, 1)
-- build query and run it to the temporary table
DECLARE @sql nvarchar(4000)
IF @SortColumn = '' OR @SortColumn IS NULL
SET @SortColumn = 'DomainName'
SET @sql = '
DECLARE @Domains TABLE
(
ItemPosition int IDENTITY(1,1),
DomainID int
)
INSERT INTO @Domains (DomainID)
SELECT
D.DomainID
FROM Domains AS D
INNER JOIN Packages AS P ON D.PackageID = P.PackageID
INNER JOIN UsersDetailed AS U ON P.UserID = U.UserID
LEFT OUTER JOIN ServiceItems AS Z ON D.ZoneItemID = Z.ItemID
LEFT OUTER JOIN Services AS S ON Z.ServiceID = S.ServiceID
LEFT OUTER JOIN Servers AS SRV ON S.ServerID = SRV.ServerID
WHERE (D.IsInstantAlias = 0 AND D.IsDomainPointer = 0) AND
((@Recursive = 0 AND D.PackageID = @PackageID)
OR (@Recursive = 1 AND dbo.CheckPackageParent(@PackageID, D.PackageID) = 1))
AND (@ServerID = 0 OR (@ServerID > 0 AND S.ServerID = @ServerID))
'
IF @FilterColumn <> '' AND @FilterValue <> ''
SET @sql = @sql + ' AND ' + @FilterColumn + ' LIKE @FilterValue '
IF @SortColumn <> '' AND @SortColumn IS NOT NULL
SET @sql = @sql + ' ORDER BY ' + @SortColumn + ' '
SET @sql = @sql + ' SELECT COUNT(DomainID) FROM @Domains;SELECT
D.DomainID,
D.PackageID,
D.ZoneItemID,
D.DomainItemID,
D.DomainName,
D.HostingAllowed,
ISNULL(WS.ItemID, 0) AS WebSiteID,
WS.ItemName AS WebSiteName,
ISNULL(MD.ItemID, 0) AS MailDomainID,
MD.ItemName AS MailDomainName,
Z.ItemName AS ZoneName,
D.IsSubDomain,
D.IsInstantAlias,
D.IsDomainPointer,
-- packages
P.PackageName,
-- server
ISNULL(SRV.ServerID, 0) AS ServerID,
ISNULL(SRV.ServerName, '''') AS ServerName,
ISNULL(SRV.Comments, '''') AS ServerComments,
ISNULL(SRV.VirtualServer, 0) AS VirtualServer,
-- user
P.UserID,
U.Username,
U.FirstName,
U.LastName,
U.FullName,
U.RoleID,
U.Email
FROM @Domains AS SD
INNER JOIN Domains AS D ON SD.DomainID = D.DomainID
INNER JOIN Packages AS P ON D.PackageID = P.PackageID
INNER JOIN UsersDetailed AS U ON P.UserID = U.UserID
LEFT OUTER JOIN ServiceItems AS WS ON D.WebSiteID = WS.ItemID
LEFT OUTER JOIN ServiceItems AS MD ON D.MailDomainID = MD.ItemID
LEFT OUTER JOIN ServiceItems AS Z ON D.ZoneItemID = Z.ItemID
LEFT OUTER JOIN Services AS S ON Z.ServiceID = S.ServiceID
LEFT OUTER JOIN Servers AS SRV ON S.ServerID = SRV.ServerID
WHERE SD.ItemPosition BETWEEN @StartRow + 1 AND @StartRow + @MaximumRows'
exec sp_executesql @sql, N'@StartRow int, @MaximumRows int, @PackageID int, @FilterValue nvarchar(50), @ServerID int, @Recursive bit',
@StartRow, @MaximumRows, @PackageID, @FilterValue, @ServerID, @Recursive
RETURN
GO
-- Domain lookup tasks
IF NOT EXISTS (SELECT * FROM [dbo].[ScheduleTasks] WHERE [TaskID] = N'SCHEDULE_TASK_DOMAIN_LOOKUP')

View file

@ -29,6 +29,8 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;
using System.Linq;
using System.Xml;
using System.Xml.Serialization;
using WebsitePanel.Providers;
@ -38,6 +40,12 @@ namespace WebsitePanel.EnterpriseServer
{
public class DnsServerController : IImportController, IBackupController
{
private static string GetAsciiZoneName(string zoneName)
{
var idn = new IdnMapping();
return idn.GetAscii(zoneName);
}
private static DNSServer GetDNSServer(int serviceId)
{
DNSServer dns = new DNSServer();
@ -55,6 +63,9 @@ namespace WebsitePanel.EnterpriseServer
// get DNS provider
DNSServer dns = GetDNSServer(serviceId);
// Ensure zoneName is in ascii before saving to database
zoneName = GetAsciiZoneName(zoneName);
// check if zone already exists
if (dns.ZoneExists(zoneName))
return BusinessErrorCodes.ERROR_DNS_ZONE_EXISTS;
@ -199,7 +210,7 @@ namespace WebsitePanel.EnterpriseServer
{
// zone item
DnsZone zone = primaryZone ? new DnsZone() : new SecondaryDnsZone();
zone.Name = zoneName;
zone.Name = GetAsciiZoneName(zoneName);
zone.PackageId = spaceId;
zone.ServiceId = serviceId;
int zoneItemId = PackageController.AddPackageItem(zone);
@ -280,6 +291,8 @@ namespace WebsitePanel.EnterpriseServer
foreach (GlobalDnsRecord record in records)
{
domainName = GetAsciiZoneName(domainName);
DnsRecord rr = new DnsRecord();
rr.RecordType = (DnsRecordType)Enum.Parse(typeof(DnsRecordType), record.RecordType, true);
rr.RecordName = Utils.ReplaceStringVariable(record.RecordName, "host_name", hostName, true);
@ -359,8 +372,11 @@ namespace WebsitePanel.EnterpriseServer
DNSServer dns = new DNSServer();
ServiceProviderProxy.Init(dns, serviceId);
// IDN: The list of importable names is populated with unicode names, to make it easier for the user
var idn = new IdnMapping();
if (itemType == typeof(DnsZone))
items.AddRange(dns.GetZones());
items.AddRange(dns.GetZones().Select(z => idn.GetUnicode(z)));
return items;
}
@ -377,7 +393,7 @@ namespace WebsitePanel.EnterpriseServer
{
// add DNS zone
DnsZone zone = new DnsZone();
zone.Name = itemName;
zone.Name = GetAsciiZoneName(itemName);
zone.ServiceId = serviceId;
zone.PackageId = packageId;
int zoneId = PackageController.AddPackageItem(zone);

View file

@ -2776,7 +2776,7 @@ namespace WebsitePanel.EnterpriseServer
DNSServer dns = new DNSServer();
ServiceProviderProxy.Init(dns, zoneItem.ServiceId);
return dns.GetZoneRecords(domain.DomainName);
return dns.GetZoneRecords(zoneItem.Name);
}
return new DnsRecord[] { };

View file

@ -28,6 +28,7 @@
using System;
using System.ComponentModel;
using System.Globalization;
using System.Web.Services;
using System.Web.Services.Protocols;
using WebsitePanel.Providers;
@ -51,6 +52,12 @@ namespace WebsitePanel.Server
get { return (IDnsServer)Provider; }
}
private string GetAsciiZoneName(string zoneName)
{
var idn = new IdnMapping();
return idn.GetAscii(zoneName);
}
#region Zones
[WebMethod, SoapHeader("settings")]
public bool ZoneExists(string zoneName)
@ -58,7 +65,7 @@ namespace WebsitePanel.Server
try
{
Log.WriteStart("'{0}' ZoneExists", ProviderSettings.ProviderName);
bool result = DnsProvider.ZoneExists(zoneName);
bool result = DnsProvider.ZoneExists(GetAsciiZoneName(zoneName));
Log.WriteEnd("'{0}' ZoneExists", ProviderSettings.ProviderName);
return result;
}
@ -92,7 +99,7 @@ namespace WebsitePanel.Server
try
{
Log.WriteStart("'{0}' AddPrimaryZone", ProviderSettings.ProviderName);
DnsProvider.AddPrimaryZone(zoneName, secondaryServers);
DnsProvider.AddPrimaryZone(GetAsciiZoneName(zoneName), secondaryServers);
Log.WriteEnd("'{0}' AddPrimaryZone", ProviderSettings.ProviderName);
}
catch (Exception ex)
@ -108,7 +115,7 @@ namespace WebsitePanel.Server
try
{
Log.WriteStart("'{0}' AddSecondaryZone", ProviderSettings.ProviderName);
DnsProvider.AddSecondaryZone(zoneName, masterServers);
DnsProvider.AddSecondaryZone(GetAsciiZoneName(zoneName), masterServers);
Log.WriteEnd("'{0}' AddSecondaryZone", ProviderSettings.ProviderName);
}
catch (Exception ex)
@ -124,7 +131,7 @@ namespace WebsitePanel.Server
try
{
Log.WriteStart("'{0}' DeleteZone", ProviderSettings.ProviderName);
DnsProvider.DeleteZone(zoneName);
DnsProvider.DeleteZone(GetAsciiZoneName(zoneName));
Log.WriteEnd("'{0}' DeleteZone", ProviderSettings.ProviderName);
}
catch (Exception ex)
@ -140,7 +147,7 @@ namespace WebsitePanel.Server
try
{
Log.WriteStart("'{0}' UpdateSoaRecord", ProviderSettings.ProviderName);
DnsProvider.UpdateSoaRecord(zoneName, host, primaryNsServer, primaryPerson);
DnsProvider.UpdateSoaRecord(GetAsciiZoneName(zoneName), host, primaryNsServer, primaryPerson);
Log.WriteEnd("'{0}' UpdateSoaRecord", ProviderSettings.ProviderName);
}
catch (Exception ex)
@ -158,7 +165,7 @@ namespace WebsitePanel.Server
try
{
Log.WriteStart("'{0}' GetZoneRecords", ProviderSettings.ProviderName);
DnsRecord[] result = DnsProvider.GetZoneRecords(zoneName);
DnsRecord[] result = DnsProvider.GetZoneRecords(GetAsciiZoneName(zoneName));
Log.WriteEnd("'{0}' GetZoneRecords", ProviderSettings.ProviderName);
return result;
}
@ -175,7 +182,7 @@ namespace WebsitePanel.Server
try
{
Log.WriteStart("'{0}' AddZoneRecord", ProviderSettings.ProviderName);
DnsProvider.AddZoneRecord(zoneName, record);
DnsProvider.AddZoneRecord(GetAsciiZoneName(zoneName), record);
Log.WriteEnd("'{0}' AddZoneRecord", ProviderSettings.ProviderName);
}
catch (Exception ex)
@ -191,7 +198,7 @@ namespace WebsitePanel.Server
try
{
Log.WriteStart("'{0}' DeleteZoneRecord", ProviderSettings.ProviderName);
DnsProvider.DeleteZoneRecord(zoneName, record);
DnsProvider.DeleteZoneRecord(GetAsciiZoneName(zoneName), record);
Log.WriteEnd("'{0}' DeleteZoneRecord", ProviderSettings.ProviderName);
}
catch (Exception ex)
@ -207,7 +214,7 @@ namespace WebsitePanel.Server
try
{
Log.WriteStart("'{0}' AddZoneRecords", ProviderSettings.ProviderName);
DnsProvider.AddZoneRecords(zoneName, records);
DnsProvider.AddZoneRecords(GetAsciiZoneName(zoneName), records);
Log.WriteEnd("'{0}' AddZoneRecords", ProviderSettings.ProviderName);
}
catch (Exception ex)
@ -223,7 +230,7 @@ namespace WebsitePanel.Server
try
{
Log.WriteStart("'{0}' DeleteZoneRecords", ProviderSettings.ProviderName);
DnsProvider.DeleteZoneRecords(zoneName, records);
DnsProvider.DeleteZoneRecords(GetAsciiZoneName(zoneName), records);
Log.WriteEnd("'{0}' DeleteZoneRecords", ProviderSettings.ProviderName);
}
catch (Exception ex)

View file

@ -144,18 +144,6 @@
<data name="DescribeEnableDns.Text" xml:space="preserve">
<value>Tick this checkbox if DNS zone for this domain will be located on name servers of your hosting provider. Make sure you changed name servers in the domain registrar control panel.</value>
</data>
<data name="DomainFormatValidator.ErrorMessage" xml:space="preserve">
<value>Please, enter correct domain name, for example "mydomain.com" or "sub.mydomain.com".</value>
</data>
<data name="DomainFormatValidator.Text" xml:space="preserve">
<value>*</value>
</data>
<data name="DomainRequiredValidator.ErrorMessage" xml:space="preserve">
<value>Please enter domain name</value>
</data>
<data name="DomainRequiredValidator.Text" xml:space="preserve">
<value>*</value>
</data>
<data name="EnableDns.Text" xml:space="preserve">
<value>Enable DNS</value>
</data>
@ -168,18 +156,6 @@
<data name="PointWebSite.Text" xml:space="preserve">
<value>Assign to existing Web Site</value>
</data>
<data name="SubDomainFormatValidator.ErrorMessage" xml:space="preserve">
<value>Please, enter correct sub-domain name, for example "subdomain" or "sub.subdomain".</value>
</data>
<data name="SubDomainFormatValidator.Text" xml:space="preserve">
<value>*</value>
</data>
<data name="SubDomainRequiredValidator.ErrorMessage" xml:space="preserve">
<value>Please enter sub-domain name</value>
</data>
<data name="SubDomainRequiredValidator.Text" xml:space="preserve">
<value>*</value>
</data>
<data name="lblHostName.Text" xml:space="preserve">
<value>Hostname:</value>
</data>

View file

@ -159,7 +159,7 @@ namespace WebsitePanel.Portal
foreach (string part in parts)
if (part.Trim() != "" && !list.Contains(part.Trim()))
list.Add(part);
return (string[])list.ToArray(typeof(string));
return (string[]) list.ToArray(typeof (string));
}
public static string ReplaceStringVariable(string str, string variable, string value)
@ -172,7 +172,7 @@ namespace WebsitePanel.Portal
{
long length = stream.Length;
byte[] content = new byte[length];
stream.Read(content, 0, (int)length);
stream.Read(content, 0, (int) length);
stream.Close();
return content;
}
@ -231,7 +231,7 @@ namespace WebsitePanel.Portal
selValues.Add(item.Value);
}
string cookieVal = String.Join(",", (string[])selValues.ToArray(typeof(string)));
string cookieVal = String.Join(",", (string[]) selValues.ToArray(typeof (string)));
// create cookie
HttpCookie cookie = new HttpCookie(ctrl.UniqueID, cookieVal);
@ -251,7 +251,7 @@ namespace WebsitePanel.Portal
foreach (ListItem item in ctrl.Items)
item.Selected = false;
string[] vals = cookie.Value.Split(new char[] { ',' });
string[] vals = cookie.Value.Split(new char[] {','});
foreach (string val in vals)
{
ListItem item = ctrl.Items.FindByValue(val);
@ -278,9 +278,9 @@ namespace WebsitePanel.Portal
// Convert 4 bytes into a 32-bit integer value.
int seed = (randomBytes[0] & 0x7f) << 24 |
randomBytes[1] << 16 |
randomBytes[2] << 8 |
randomBytes[3];
randomBytes[1] << 16 |
randomBytes[2] << 8 |
randomBytes[3];
Random rnd = new Random(seed);
@ -294,17 +294,38 @@ namespace WebsitePanel.Portal
public static bool CheckQouta(string key, PackageContext cntx)
{
return cntx.Quotas.ContainsKey(key) &&
((cntx.Quotas[key].QuotaAllocatedValue == 1 && cntx.Quotas[key].QuotaTypeId == 1) ||
(cntx.Quotas[key].QuotaTypeId != 1 && (cntx.Quotas[key].QuotaAllocatedValue > 0 || cntx.Quotas[key].QuotaAllocatedValue == -1)));
((cntx.Quotas[key].QuotaAllocatedValue == 1 && cntx.Quotas[key].QuotaTypeId == 1) ||
(cntx.Quotas[key].QuotaTypeId != 1 && (cntx.Quotas[key].QuotaAllocatedValue > 0 || cntx.Quotas[key].QuotaAllocatedValue == -1)));
}
public static bool CheckQouta(string key, HostingPlanContext cntx)
{
return cntx.Quotas.ContainsKey(key) &&
((cntx.Quotas[key].QuotaAllocatedValue == 1 && cntx.Quotas[key].QuotaTypeId == 1) ||
(cntx.Quotas[key].QuotaTypeId != 1 && (cntx.Quotas[key].QuotaAllocatedValue > 0 || cntx.Quotas[key].QuotaAllocatedValue == -1)));
((cntx.Quotas[key].QuotaAllocatedValue == 1 && cntx.Quotas[key].QuotaTypeId == 1) ||
(cntx.Quotas[key].QuotaTypeId != 1 && (cntx.Quotas[key].QuotaAllocatedValue > 0 || cntx.Quotas[key].QuotaAllocatedValue == -1)));
}
public static bool IsIdnDomain(string domainName)
{
if (string.IsNullOrEmpty(domainName))
{
return false;
}
var idn = new IdnMapping();
return idn.GetAscii(domainName) != domainName;
}
public static string UnicodeToAscii(string domainName)
{
if (string.IsNullOrEmpty(domainName))
{
return string.Empty;
}
var idn = new IdnMapping();
return idn.GetAscii(domainName);
}
}
}

View file

@ -30,6 +30,7 @@ using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Globalization;
using System.Web;
using System.Web.Security;
using System.Web.UI;
@ -57,6 +58,10 @@ namespace WebsitePanel.Portal
// domain name
DomainInfo domain = ES.Services.Servers.GetDomain(PanelRequest.DomainID);
litDomainName.Text = domain.DomainName;
if (Utils.IsIdnDomain(domain.DomainName))
{
litDomainName.Text = string.Format("{0} ({1})", Utils.UnicodeToAscii(domain.DomainName), domain.DomainName);
}
}
}

View file

@ -1,33 +1,21 @@
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="DomainsAddDomain.ascx.cs" Inherits="WebsitePanel.Portal.DomainsAddDomain" %>
<%@ Register Src="UserControls/EnableAsyncTasksSupport.ascx" TagName="EnableAsyncTasksSupport" TagPrefix="wsp" %>
<%@ Register Src="DomainsSelectDomainControl.ascx" TagName="DomainsSelectDomainControl" TagPrefix="uc1" %>
<%@ Register Src="UserControls/DomainControl.ascx" TagName="DomainControl" TagPrefix="wsp" %>
<%@ Register Src="UserControls/CollapsiblePanel.ascx" TagPrefix="wsp" TagName="CollapsiblePanel" %>
<wsp:EnableAsyncTasksSupport id="asyncTasks" runat="server" />
<asp:ValidationSummary ID="summary" runat="server" ShowMessageBox="true" ShowSummary="false" ValidationGroup="Domain" />
<asp:ValidationSummary ID="summary" runat="server" ShowMessageBox="true" ShowSummary="true" ValidationGroup="Domain" />
<div class="FormBody">
<p id="DomainPanel" runat="server" style="padding: 15px 0 15px 5px;" visible="false">
<asp:TextBox ID="DomainName" runat="server" Width="300" CssClass="HugeTextBox"></asp:TextBox>
<asp:RequiredFieldValidator id="DomainRequiredValidator" runat="server" meta:resourcekey="DomainRequiredValidator"
ControlToValidate="DomainName" Display="Dynamic" ValidationGroup="Domain" SetFocusOnError="true"></asp:RequiredFieldValidator>
<asp:RegularExpressionValidator id="DomainFormatValidator" runat="server" meta:resourcekey="DomainFormatValidator"
ControlToValidate="DomainName" Display="Dynamic" ValidationGroup="Domain" SetFocusOnError="true"
ValidationExpression="^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.){1,10}[a-zA-Z]{2,15}$"></asp:RegularExpressionValidator>
</p>
<p id="SubDomainPanel" runat="server" style="padding: 15px 0 15px 5px;" visible="false">
<asp:TextBox ID="SubDomainName" runat="server" Width="150" CssClass="TextBox100"></asp:TextBox>
.
<asp:DropDownList ID="DomainsList" Runat="server" CssClass="NormalTextBox" DataTextField="DomainName" DataValueField="DomainName"></asp:DropDownList>
<asp:RequiredFieldValidator id="SubDomainRequiredValidator" runat="server" meta:resourcekey="SubDomainRequiredValidator"
ControlToValidate="SubDomainName" Display="Dynamic" ValidationGroup="Domain" SetFocusOnError="true"></asp:RequiredFieldValidator>
<asp:RegularExpressionValidator id="SubDomainFormatValidator" runat="server" meta:resourcekey="SubDomainFormatValidator"
ControlToValidate="SubDomainName" Display="Dynamic" ValidationGroup="Domain" SetFocusOnError="true"
ValidationExpression="^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)(\.[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?){0,9}$"></asp:RegularExpressionValidator>
<p id="DomainPanel" runat="server" style="padding: 15px 0 15px 5px;">
<wsp:DomainControl ID="DomainName" runat="server" RequiredEnabled="True" ValidationGroup="Domain" AutoPostBack="True" OnTextChanged="DomainName_TextChanged"></wsp:DomainControl>
</p>
<%--
<p id="SubDomainPanel" runat="server" style="padding: 15px 0 15px 5px;" visible="false">
<wsp:DomainControl ID="SubDomainName" runat="server" RequiredEnabled="True" IsSubDomain="True" ValidationGroup="Domain"></wsp:DomainControl>
</p>--%>
<wsp:CollapsiblePanel id="OptionsPanelHeader" runat="server"
TargetControlID="OptionsPanel" resourcekey="OptionsPanelHeader" Text="Provisioning options">

View file

@ -30,6 +30,7 @@ using System;
using System.Web;
using WebsitePanel.EnterpriseServer;
using System.Collections.Generic;
using WebsitePanel.Portal.UserControls;
namespace WebsitePanel.Portal
{
@ -82,12 +83,12 @@ namespace WebsitePanel.Portal
if (type == DomainType.Domain || type == DomainType.DomainPointer)
{
// domains
DomainPanel.Visible = true;
DomainName.IsSubDomain = false;
}
else
{
// sub-domains
SubDomainPanel.Visible = true;
DomainName.IsSubDomain = true;
// fill sub-domains
if (!IsPostBack)
@ -178,14 +179,14 @@ namespace WebsitePanel.Portal
if (!domain.IsDomainPointer && !domain.IsSubDomain && !domain.IsInstantAlias)
domains.Add(domain);
DomainsList.DataSource = domains;
DomainsList.DataBind();
DomainName.DataSource = domains;
DomainName.DataBind();
}
private void BindResellerDomains()
{
DomainsList.DataSource = ES.Services.Servers.GetResellerDomains(PanelSecurity.PackageId);
DomainsList.DataBind();
DomainName.DataSource = ES.Services.Servers.GetResellerDomains(PanelSecurity.PackageId);
DomainName.DataBind();
}
private void AddDomain()
@ -197,9 +198,7 @@ namespace WebsitePanel.Portal
DomainType type = GetDomainType(Request["DomainType"]);
// get domain name
string domainName = DomainName.Text.Trim();
if (type == DomainType.SubDomain || type == DomainType.ProviderSubDomain)
domainName = SubDomainName.Text.Trim() + "." + DomainsList.SelectedValue;
var domainName = DomainName.Text;
int pointWebSiteId = 0;
int pointMailDomainId = 0;
@ -263,5 +262,13 @@ namespace WebsitePanel.Portal
{
AddDomain();
}
protected void DomainName_TextChanged(object sender, DomainControl.DomainNameEventArgs e)
{
// If the choosen domain is a idn domain, don't allow to create mail
var isIdn = Utils.IsIdnDomain(e.DomainName);
PointMailDomainPanel.Enabled = !isIdn;
PointMailDomain.Checked = !isIdn;
}
}
}

View file

@ -1,31 +1,3 @@
// Copyright (c) 2014, 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.
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
@ -74,70 +46,7 @@ namespace WebsitePanel.Portal {
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.TextBox DomainName;
/// <summary>
/// DomainRequiredValidator control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.RequiredFieldValidator DomainRequiredValidator;
/// <summary>
/// DomainFormatValidator control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.RegularExpressionValidator DomainFormatValidator;
/// <summary>
/// SubDomainPanel control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.HtmlControls.HtmlGenericControl SubDomainPanel;
/// <summary>
/// SubDomainName control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.TextBox SubDomainName;
/// <summary>
/// DomainsList control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.DropDownList DomainsList;
/// <summary>
/// SubDomainRequiredValidator control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.RequiredFieldValidator SubDomainRequiredValidator;
/// <summary>
/// SubDomainFormatValidator control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.RegularExpressionValidator SubDomainFormatValidator;
protected global::WebsitePanel.Portal.UserControls.DomainControl DomainName;
/// <summary>
/// OptionsPanelHeader control.

View file

@ -30,6 +30,7 @@ using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
@ -44,6 +45,12 @@ namespace WebsitePanel.Portal
{
public partial class DomainsSelectDomainControl : WebsitePanelControlBase
{
public bool HideIdnDomains
{
get { return (ViewState["HideIdnDomains"] != null) && (bool)ViewState["HideIdnDomains"]; }
set { ViewState["HideIdnDomains"] = value; }
}
public bool HideWebSites
{
get { return (ViewState["HideWebSites"] != null) ? (bool)ViewState["HideWebSites"] : false; }
@ -116,6 +123,11 @@ namespace WebsitePanel.Portal
{
DomainInfo[] domains = ES.Services.Servers.GetMyDomains(PackageId);
if (HideIdnDomains)
{
domains = domains.Where(d => !Utils.IsIdnDomain(d.DomainName)).ToArray();
}
WebSite[] sites = null;
Hashtable htSites = new Hashtable();
Hashtable htMailDomainPointers = new Hashtable();

View file

@ -28,6 +28,7 @@
using System;
using System.Data;
using System.Linq;
using System.Text;
using System.Collections.Generic;
@ -40,7 +41,7 @@ namespace WebsitePanel.Portal.ExchangeServer
{
protected void Page_Load(object sender, EventArgs e)
{
DomainInfo[] domains = ES.Services.Servers.GetMyDomains(PanelSecurity.PackageId);
DomainInfo[] domains = ES.Services.Servers.GetMyDomains(PanelSecurity.PackageId).Where(d => !Utils.IsIdnDomain(d.DomainName)).ToArray();
Organization[] orgs = ES.Services.Organizations.GetOrganizations(PanelSecurity.PackageId, false);

View file

@ -28,6 +28,7 @@
using System;
using System.Data;
using System.Linq;
using System.Text;
using System.Collections.Generic;
@ -40,7 +41,7 @@ namespace WebsitePanel.Portal.ExchangeServer
{
protected void Page_Load(object sender, EventArgs e)
{
DomainInfo[] domains = ES.Services.Servers.GetMyDomains(PanelSecurity.PackageId);
DomainInfo[] domains = ES.Services.Servers.GetMyDomains(PanelSecurity.PackageId).Where(d => !Utils.IsIdnDomain(d.DomainName)).ToArray();
Organization[] orgs = ES.Services.Organizations.GetOrganizations(PanelSecurity.PackageId, false);

View file

@ -28,6 +28,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using WebsitePanel.EnterpriseServer;
using WebsitePanel.Providers.HostedSolution;
@ -37,7 +38,7 @@ namespace WebsitePanel.Portal.ExchangeServer
{
protected void Page_Load(object sender, EventArgs e)
{
DomainInfo[] domains = ES.Services.Servers.GetMyDomains(PanelSecurity.PackageId);
DomainInfo[] domains = ES.Services.Servers.GetMyDomains(PanelSecurity.PackageId).Where(d => !Utils.IsIdnDomain(d.DomainName)).ToArray();
Organization[] orgs = ES.Services.Organizations.GetOrganizations(PanelSecurity.PackageId, false);
var list = new List<OrganizationDomainName>();
SetPolicy(PanelSecurity.PackageId, UserSettings.EXCHANGE_POLICY, "OrgIdPolicy");

View file

@ -6,7 +6,7 @@
<td class="SubHead" width="200" nowrap><asp:Label ID="lblDomainName" runat="server" meta:resourcekey="lblDomainName" Text="Domain name:"></asp:Label></td>
<td width="100%">
<uc1:DomainsSelectDomainControl ID="domainsSelectDomainControl" runat="server"
HideMailDomains="true" HideDomainsSubDomains="false" HideInstantAlias="false" HideDomainPointers="true"/>
HideMailDomains="true" HideDomainsSubDomains="false" HideInstantAlias="false" HideDomainPointers="true" HideIdnDomains="True"/>
</td>
</tr>
</table>

View file

@ -9,7 +9,7 @@
<td id="EditEmailPanel" runat="server">
<uc2:UsernameControl ID="txtName" runat="server" width="120px" />
&nbsp;@&nbsp;
<dnc:SelectDomain id="domainsSelectDomainControl" runat="server" HideDomainPointers="true" HideInstantAlias="false" HideMailDomainPointers="true"></dnc:SelectDomain>
<dnc:SelectDomain id="domainsSelectDomainControl" runat="server" HideDomainPointers="true" HideInstantAlias="false" HideMailDomainPointers="true" HideIdnDomains="True"></dnc:SelectDomain>
</td>
<td id="DisplayEmailPanel" runat="server">
<asp:Label ID="litName" Runat="server" Visible="False" CssClass="Huge"></asp:Label>

View file

@ -0,0 +1,138 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="DomainFormatValidator.ErrorMessage" xml:space="preserve">
<value>Please, enter correct domain name, for example "mydomain.com" or "sub.mydomain.com".</value>
</data>
<data name="DomainFormatValidator.Text" xml:space="preserve">
<value>*</value>
</data>
<data name="DomainRequiredValidator.ErrorMessage" xml:space="preserve">
<value>Please enter domain name</value>
</data>
<data name="DomainRequiredValidator.Text" xml:space="preserve">
<value>*</value>
</data>
<data name="SubDomainRequiredValidator.ErrorMessage" xml:space="preserve">
<value>Please enter sub-domain name</value>
</data>
<data name="SubDomainRequiredValidator.Text" xml:space="preserve">
<value>*</value>
</data>
</root>

View file

@ -0,0 +1,10 @@
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="DomainControl.ascx.cs" Inherits="WebsitePanel.Portal.UserControls.DomainControl" %>
<asp:TextBox ID="txtDomainName" runat="server" Width="300" CssClass="HugeTextBox" OnTextChanged="txtDomainName_TextChanged"></asp:TextBox>
<asp:Literal runat="server" ID="SubDomainSeparator" Visible="False">.</asp:Literal>
<asp:DropDownList ID="DomainsList" Runat="server" CssClass="NormalTextBox" DataTextField="DomainName" DataValueField="DomainName" Visible="False"></asp:DropDownList>
<asp:RequiredFieldValidator id="DomainRequiredValidator" runat="server" meta:resourcekey="DomainRequiredValidator"
ControlToValidate="txtDomainName" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
<asp:CustomValidator id="DomainFormatValidator" runat="server" meta:resourcekey="DomainFormatValidator" EnableClientScript="False" ValidateEmptyText="False"
ControlToValidate="txtDomainName" Display="Dynamic" SetFocusOnError="true" OnServerValidate="DomainFormatValidator_ServerValidate"></asp:CustomValidator>

View file

@ -0,0 +1,134 @@
// Copyright (c) 2014, 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.Text.RegularExpressions;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Globalization;
namespace WebsitePanel.Portal.UserControls
{
public partial class DomainControl : WebsitePanelControlBase
{
public class DomainNameEventArgs : EventArgs
{
public string DomainName { get; set; }
}
public event EventHandler<DomainNameEventArgs> TextChanged;
public virtual void OnTextChanged()
{
var handler = TextChanged;
if (handler != null) handler(this, new DomainNameEventArgs {DomainName = Text});
}
public object DataSource
{
set { DomainsList.DataSource = value; }
}
public bool AutoPostBack
{
get { return txtDomainName.AutoPostBack; }
set { txtDomainName.AutoPostBack = value; }
}
public Unit Width
{
get { return txtDomainName.Width; }
set { txtDomainName.Width = value; }
}
public bool RequiredEnabled
{
get { return DomainRequiredValidator.Enabled; }
set { DomainRequiredValidator.Enabled = value; }
}
public string Text
{
get
{
var domainName = txtDomainName.Text.Trim();
if (IsSubDomain)
{
domainName += "." + DomainsList.SelectedValue;
}
return domainName;
}
set { txtDomainName.Text = value; }
}
public string ValidationGroup
{
get { return DomainRequiredValidator.ValidationGroup; }
set { DomainRequiredValidator.ValidationGroup = value; DomainFormatValidator.ValidationGroup = value; }
}
public bool IsSubDomain {
get { return SubDomainSeparator.Visible; }
set
{
SubDomainSeparator.Visible = value;
DomainsList.Visible = value;
DomainRequiredValidator.Enabled = !value;
}
}
protected void Page_Load(object sender, EventArgs e)
{
}
protected new void DataBind()
{
DomainsList.DataBind();
}
protected void DomainFormatValidator_ServerValidate(object source, ServerValidateEventArgs args)
{
var idn = new IdnMapping();
try
{
var ascii = idn.GetAscii(Text);
var regex = new Regex(@"^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.){1,10}[a-zA-Z]{2,15}$");
args.IsValid = regex.IsMatch(ascii);
}
catch (Exception)
{
args.IsValid = false;
}
}
protected void txtDomainName_TextChanged(object sender, EventArgs e)
{
OnTextChanged();
}
}
}

View file

@ -0,0 +1,60 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace WebsitePanel.Portal.UserControls {
public partial class DomainControl {
/// <summary>
/// txtDomainName control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.TextBox txtDomainName;
/// <summary>
/// SubDomainSeparator control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Literal SubDomainSeparator;
/// <summary>
/// DomainsList control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.DropDownList DomainsList;
/// <summary>
/// DomainRequiredValidator control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.RequiredFieldValidator DomainRequiredValidator;
/// <summary>
/// DomainFormatValidator control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.CustomValidator DomainFormatValidator;
}
}

View file

@ -1,12 +1,11 @@
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="UserCreateSpace.ascx.cs" Inherits="WebsitePanel.Portal.UserCreateSpace" %>
<%@ Register TagPrefix="wsp" TagName="CollapsiblePanel" Src="UserControls/CollapsiblePanel.ascx" %>
<%@ Register Src="UserControls/UsernameControl.ascx" TagName="UsernameControl" TagPrefix="uc4" %>
<%@ Register Src="DomainsSelectDomainControl.ascx" TagName="DomainsSelectDomainControl" TagPrefix="uc1" %>
<%@ Register Src="UserControls/DomainControl.ascx" TagName="DomainControl" TagPrefix="wsp" %>
<%@ Register Src="UserControls/EnableAsyncTasksSupport.ascx" TagName="EnableAsyncTasksSupport" TagPrefix="wsp" %>
<wsp:EnableAsyncTasksSupport id="asyncTasks" runat="server"/>
<asp:ValidationSummary ID="summary" runat="server" ShowMessageBox="true" ShowSummary="false" ValidationGroup="CreateSpace" />
<asp:ValidationSummary ID="summary" runat="server" ShowMessageBox="true" ShowSummary="true" ValidationGroup="CreateSpace" />
<asp:UpdatePanel runat="server" ID="updatePanelSpace" UpdateMode="Conditional" ChildrenAsTriggers="true">
<ContentTemplate>
@ -74,12 +73,7 @@
<asp:Localize ID="locDomainName" runat="server" meta:resourcekey="locDomainName" Text="Domain name:"></asp:Localize>
</td>
<td class="Normal" width="100%">
<asp:TextBox ID="txtDomainName" runat="server" CssClass="NormalTextBox" Width="250px"></asp:TextBox>
<asp:RequiredFieldValidator id="DomainRequiredValidator" runat="server" meta:resourcekey="DomainRequiredValidator"
ControlToValidate="txtDomainName" Display="Dynamic" ValidationGroup="CreateSpace" SetFocusOnError="true"></asp:RequiredFieldValidator>
<asp:RegularExpressionValidator id="DomainFormatValidator" runat="server" meta:resourcekey="DomainFormatValidator"
ControlToValidate="txtDomainName" Display="Dynamic" ValidationGroup="CreateSpace" SetFocusOnError="true"
ValidationExpression="^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.){1,10}[a-zA-Z]{2,15}$"></asp:RegularExpressionValidator>
<wsp:DomainControl ID="txtDomainName" runat="server" RequiredEnabled="True" ValidationGroup="CreateSpace"></wsp:DomainControl>
</td>
</tr>
</table>

View file

@ -163,25 +163,7 @@ namespace WebsitePanel.Portal {
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.TextBox txtDomainName;
/// <summary>
/// DomainRequiredValidator control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.RequiredFieldValidator DomainRequiredValidator;
/// <summary>
/// DomainFormatValidator control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.RegularExpressionValidator DomainFormatValidator;
protected global::WebsitePanel.Portal.UserControls.DomainControl txtDomainName;
/// <summary>
/// fsWeb control.

View file

@ -773,6 +773,13 @@
<Compile Include="SkinControls\SpaceOrganizationsSelector.ascx.designer.cs">
<DependentUpon>SpaceOrganizationsSelector.ascx</DependentUpon>
</Compile>
<Compile Include="UserControls\DomainControl.ascx.cs">
<DependentUpon>DomainControl.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="UserControls\DomainControl.ascx.designer.cs">
<DependentUpon>DomainControl.ascx</DependentUpon>
</Compile>
<Compile Include="UserControls\DomainListControlBase.cs">
<SubType>ASPXCodeBehind</SubType>
</Compile>
@ -4379,6 +4386,7 @@
<Content Include="SettingsLyncUserPlansPolicy.ascx" />
<Content Include="SkinControls\SpaceOrganizationsSelector.ascx" />
<Content Include="SettingsExchangeRetentionPolicyTag.ascx" />
<Content Include="UserControls\DomainControl.ascx" />
<Content Include="UserControls\EditFeedsList.ascx" />
<Content Include="UserControls\OrgIdPolicyEditor.ascx" />
<Content Include="UserControls\OrgPolicyEditor.ascx" />
@ -5626,6 +5634,7 @@
<Content Include="RDS\UserControls\App_LocalResources\RDSCollectionServers.ascx.resx" />
<Content Include="RDS\UserControls\App_LocalResources\RDSCollectionApps.ascx.resx" />
<Content Include="ProviderControls\App_LocalResources\RDS_Settings.ascx.resx" />
<Content Include="UserControls\App_LocalResources\DomainControl.ascx.resx" />
<EmbeddedResource Include="UserControls\App_LocalResources\EditDomainsList.ascx.resx">
<SubType>Designer</SubType>
</EmbeddedResource>