Domain Expiration Task Added

This commit is contained in:
vfedosevich 2014-12-08 04:15:23 -08:00
parent 133de4b747
commit bb0b92e565
20 changed files with 834 additions and 87 deletions

View file

@ -6109,6 +6109,40 @@ INSERT [dbo].[ScheduleTaskParameters] ([TaskID], [ParameterID], [DataTypeID], [D
END
GO
-- Domain Expiration Task
IF NOT EXISTS (SELECT * FROM [dbo].[ScheduleTasks] WHERE [TaskID] = N'SCHEDULE_TASK_DOMAIN_EXPIRATION')
BEGIN
INSERT [dbo].[ScheduleTasks] ([TaskID], [TaskType], [RoleID]) VALUES (N'SCHEDULE_TASK_DOMAIN_EXPIRATION', N'WebsitePanel.EnterpriseServer.DomainExpirationTask, WebsitePanel.EnterpriseServer.Code', 1)
END
GO
IF NOT EXISTS (SELECT * FROM [dbo].[ScheduleTaskViewConfiguration] WHERE [TaskID] = N'SCHEDULE_TASK_DOMAIN_EXPIRATION')
BEGIN
INSERT [dbo].[ScheduleTaskViewConfiguration] ([TaskID], [ConfigurationID], [Environment], [Description]) VALUES (N'SCHEDULE_TASK_DOMAIN_EXPIRATION', N'ASP_NET', N'ASP.NET', N'~/DesktopModules/WebsitePanel/ScheduleTaskControls/DomainExpirationView.ascx')
END
GO
IF NOT EXISTS (SELECT * FROM [dbo].[ScheduleTaskParameters] WHERE [TaskID] = N'SCHEDULE_TASK_DOMAIN_EXPIRATION' AND [ParameterID]= N'DAYS_BEFORE' )
BEGIN
INSERT [dbo].[ScheduleTaskParameters] ([TaskID], [ParameterID], [DataTypeID], [DefaultValue], [ParameterOrder]) VALUES (N'SCHEDULE_TASK_DOMAIN_EXPIRATION', N'DAYS_BEFORE', N'String', NULL, 1)
END
GO
IF NOT EXISTS (SELECT * FROM [dbo].[ScheduleTaskParameters] WHERE [TaskID] = N'SCHEDULE_TASK_DOMAIN_EXPIRATION' AND [ParameterID]= N'MAIL_TO' )
BEGIN
INSERT [dbo].[ScheduleTaskParameters] ([TaskID], [ParameterID], [DataTypeID], [DefaultValue], [ParameterOrder]) VALUES (N'SCHEDULE_TASK_DOMAIN_EXPIRATION', N'MAIL_TO', N'String', NULL, 2)
END
GO
IF NOT EXISTS (SELECT * FROM [dbo].[ScheduleTaskParameters] WHERE [TaskID] = N'SCHEDULE_TASK_DOMAIN_EXPIRATION' AND [ParameterID]= N'ENABLE_NOTIFICATION' )
BEGIN
INSERT [dbo].[ScheduleTaskParameters] ([TaskID], [ParameterID], [DataTypeID], [DefaultValue], [ParameterOrder]) VALUES (N'SCHEDULE_TASK_DOMAIN_EXPIRATION', N'ENABLE_NOTIFICATION', N'Boolean', N'false', 3)
END
GO
-- Domain lookup tables
IF EXISTS (SELECT * FROM SYS.TABLES WHERE name = 'DomainDnsRecords')
@ -6130,6 +6164,20 @@ REFERENCES [dbo].[Domains] ([DomainID])
ON DELETE CASCADE
GO
IF NOT EXISTS(SELECT * FROM sys.columns
WHERE [name] = N'CreationDate' AND [object_id] = OBJECT_ID(N'Domains'))
BEGIN
ALTER TABLE [dbo].[Domains] ADD CreationDate DateTime null;
END
GO
IF NOT EXISTS(SELECT * FROM sys.columns
WHERE [name] = N'ExpirationDate' AND [object_id] = OBJECT_ID(N'Domains'))
BEGIN
ALTER TABLE [dbo].[Domains] ADD ExpirationDate DateTime null;
END
GO
IF EXISTS (SELECT * FROM SYS.TABLES WHERE name = 'ScheduleTasksEmailTemplates')
DROP TABLE ScheduleTasksEmailTemplates
GO
@ -6141,21 +6189,22 @@ CREATE TABLE ScheduleTasksEmailTemplates
)
GO
IF NOT EXISTS (SELECT * FROM [dbo].[ScheduleTasksEmailTemplates] WHERE [TaskID] = N'SCHEDULE_TASK_DOMAIN_LOOKUP' AND [ParameterID]= N'MAIL_BODY' )
IF NOT EXISTS (SELECT * FROM [dbo].[ScheduleTasksEmailTemplates] WHERE [TaskID] = N'SCHEDULE_TASK_DOMAIN_EXPIRATION' AND [ParameterID]= N'MAIL_BODY' )
BEGIN
INSERT [dbo].[ScheduleTasksEmailTemplates] ([TaskID], [ParameterID], [Value]) VALUES (N'SCHEDULE_TASK_DOMAIN_LOOKUP', N'MAIL_BODY', N'<html xmlns="http://www.w3.org/1999/xhtml">
INSERT [dbo].[ScheduleTasksEmailTemplates] ([TaskID], [ParameterID], [Value]) VALUES (N'SCHEDULE_TASK_DOMAIN_EXPIRATION', N'MAIL_BODY', N'
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Account Summary Information</title>
<title>Domain Expiration Information</title>
<style type="text/css">
.Summary { background-color: #ffffff; padding: 5px; }
.Summary .Header { padding: 10px 0px 10px 10px; font-size: 16pt; background-color: #E5F2FF; color: #1F4978; border-bottom: solid 2px #86B9F7; }
.Summary A { color: #0153A4; }
.Summary { background-color: ##ffffff; padding: 5px; }
.Summary .Header { padding: 10px 0px 10px 10px; font-size: 16pt; background-color: ##E5F2FF; color: ##1F4978; border-bottom: solid 2px ##86B9F7; }
.Summary A { color: ##0153A4; }
.Summary { font-family: Tahoma; font-size: 9pt; }
.Summary H1 { font-size: 1.7em; color: #1F4978; border-bottom: dotted 3px #efefef; }
.Summary H2 { font-size: 1.3em; color: #1F4978; }
.Summary TABLE { border: solid 1px #e5e5e5; }
.Summary H1 { font-size: 1.7em; color: ##1F4978; border-bottom: dotted 3px ##efefef; }
.Summary H2 { font-size: 1.3em; color: ##1F4978; }
.Summary TABLE { border: solid 1px ##e5e5e5; }
.Summary TH,
.Summary TD.Label { padding: 5px; font-size: 8pt; font-weight: bold; background-color: #f5f5f5; }
.Summary TD.Label { padding: 5px; font-size: 8pt; font-weight: bold; background-color: ##f5f5f5; }
.Summary TD { padding: 8px; font-size: 9pt; }
.Summary UL LI { font-size: 1.1em; font-weight: bold; }
.Summary UL UL LI { font-size: 0.9em; font-weight: normal; }
@ -6166,29 +6215,35 @@ INSERT [dbo].[ScheduleTasksEmailTemplates] ([TaskID], [ParameterID], [Value]) VA
<a name="top"></a>
<div class="Header">
MX and NS Information
Domain Expiration Information
</div>
<ad:if test="#user#">
<p>
Hello!,
Hello #user.FirstName#,
</p>
</ad:if>
<p>
Please, find below details for mx and ns changes.
Please, find below details of your domain expiration information.
</p>
<table>
<thead>
<tr>
<th>Domain</th>
<th>DNS</th>
<th>Record Type</th>
<th>DataBase Value</th>
<th>Dns Value</th>
<th>Customer</th>
<th>Expiration Date</th>
</tr>
</thead>
<tbody>
[RecordRow]
<ad:foreach collection="#Domains#" var="Domain" index="i">
<tr>
<td>#Domain.DomainName#</td>
<td>#Domain.Customer#</td>
<td>#Domain.ExpirationDate#</td>
</tr>
</ad:foreach>
</tbody>
</table>
@ -6199,27 +6254,31 @@ If you have any questions regarding your hosting account, feel free to contact o
<p>
Best regards
</p>
</div>
</body>
</html>')
</p>')
END
GO
IF NOT EXISTS (SELECT * FROM [dbo].[ScheduleTasksEmailTemplates] WHERE [TaskID] = N'SCHEDULE_TASK_DOMAIN_LOOKUP' AND [ParameterID]= N'MAIL_DOMAIN_RECORD' )
BEGIN
INSERT [dbo].[ScheduleTasksEmailTemplates] ([TaskID], [ParameterID], [Value]) VALUES (N'SCHEDULE_TASK_DOMAIN_LOOKUP', N'MAIL_DOMAIN_RECORD',N'<tr>
<td>[domain]</td>
<td>[dns]</td>
<td>[recordType]</td>
<td>[dbRecord]</td>
<td>[dnsRecord]</td>
</tr>')
END
GO
-- Procedures for Domain lookup service
-- Procedures for Domai lookup service
IF EXISTS (SELECT * FROM SYS.OBJECTS WHERE type = 'P' AND name = 'GetAllPackages')
DROP PROCEDURE GetAllPackages
GO
CREATE PROCEDURE [dbo].[GetAllPackages]
AS
SELECT
[PackageID]
,[ParentPackageID]
,[UserID]
,[PackageName]
,[PackageComments]
,[ServerID]
,[StatusID]
,[PlanID]
,[PurchaseDate]
,[OverrideQuotas]
,[BandwidthUpdated]
FROM [dbo].[Packages]
GO
IF EXISTS (SELECT * FROM SYS.OBJECTS WHERE type = 'P' AND name = 'GetScheduleTaskEmailTemplate')
DROP PROCEDURE GetScheduleTaskEmailTemplate
@ -6237,18 +6296,6 @@ SELECT
FROM [dbo].[ScheduleTasksEmailTemplates] where [TaskID] = @TaskID AND [ParameterID] = @ParameterID
GO
IF EXISTS (SELECT * FROM SYS.OBJECTS WHERE type = 'P' AND name = 'GetAllPackageIds')
DROP PROCEDURE GetAllPackageIds
GO
CREATE PROCEDURE [dbo].GetAllPackageIds
AS
SELECT
[PackageID]
FROM [dbo].[Packages]
GO
IF EXISTS (SELECT * FROM SYS.OBJECTS WHERE type = 'P' AND name = 'GetDomainDnsRecords')
DROP PROCEDURE GetDomainDnsRecords
GO
@ -6312,8 +6359,178 @@ CREATE PROCEDURE [dbo].[DeleteDomainDnsRecord]
@Id INT
)
AS
DELETE FROM DomainDnsRecords
WHERE Id = @Id
GO
--Domain Expiration Stored Procedures
IF EXISTS (SELECT * FROM SYS.OBJECTS WHERE type = 'P' AND name = 'UpdateDomainCreationDate')
DROP PROCEDURE UpdateDomainCreationDate
GO
CREATE PROCEDURE [dbo].UpdateDomainCreationDate
(
@DomainId INT,
@Date DateTime
)
AS
UPDATE [dbo].[Domains] SET [CreationDate] = @Date WHERE [DomainID] = @DomainId
GO
IF EXISTS (SELECT * FROM SYS.OBJECTS WHERE type = 'P' AND name = 'UpdateDomainExpirationDate')
DROP PROCEDURE UpdateDomainExpirationDate
GO
CREATE PROCEDURE [dbo].UpdateDomainExpirationDate
(
@DomainId INT,
@Date DateTime
)
AS
UPDATE [dbo].[Domains] SET [ExpirationDate] = @Date WHERE [DomainID] = @DomainId
GO
--Updating Domain procedures
IF EXISTS (SELECT * FROM SYS.OBJECTS WHERE type = 'P' AND name = 'GetDomains')
DROP PROCEDURE GetDomains
GO
CREATE PROCEDURE [dbo].[GetDomains]
(
@ActorID int,
@PackageID int,
@Recursive bit = 1
)
AS
-- check rights
IF dbo.CheckActorPackageRights(@ActorID, @PackageID) = 0
RAISERROR('You are not allowed to access this package', 16, 1)
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.CreationDate,
D.ExpirationDate,
D.IsDomainPointer
FROM Domains AS D
INNER JOIN PackagesTree(@PackageID, @Recursive) AS PT ON D.PackageID = PT.PackageID
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
RETURN
GO
IF EXISTS (SELECT * FROM SYS.OBJECTS WHERE type = 'P' AND name = 'GetDomainsPaged')
DROP PROCEDURE GetDomainsPaged
GO
CREATE 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(2000)
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,
D.IsSubDomain,
D.IsInstantAlias,
D.IsDomainPointer,
D.ExpirationDate,
P.PackageName,
ISNULL(SRV.ServerID, 0) AS ServerID,
ISNULL(SRV.ServerName, '''') AS ServerName,
ISNULL(SRV.Comments, '''') AS ServerComments,
ISNULL(SRV.VirtualServer, 0) AS VirtualServer,
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

Binary file not shown.

View file

@ -147,5 +147,8 @@ namespace WebsitePanel.EnterpriseServer
get { return this.instantAliasName; }
set { this.instantAliasName = value; }
}
public DateTime? CreationDate { get; set; }
public DateTime? ExpirationDate { get; set; }
}
}

View file

@ -4723,12 +4723,12 @@ namespace WebsitePanel.EnterpriseServer
#region MX|NX Services
public static IDataReader GetAllPackagesIds()
public static IDataReader GetAllPackages()
{
return SqlHelper.ExecuteReader(
ConnectionString,
CommandType.StoredProcedure,
"GetAllPackageIds"
"GetAllPackages"
);
}
@ -4776,7 +4776,28 @@ namespace WebsitePanel.EnterpriseServer
"DeleteDomainDnsRecord",
new SqlParameter("@Id", id)
);
}
}
public static void UpdateDomainCreationDate(int domainId, DateTime date)
{
UpdateDomainDate(domainId, "UpdateDomainCreationDate", date);
}
public static void UpdateDomainExpirationDate(int domainId, DateTime date)
{
UpdateDomainDate(domainId, "UpdateDomainExpirationDate", date);
}
private static void UpdateDomainDate(int domainId, string stroredProcedure, DateTime date)
{
SqlHelper.ExecuteReader(
ConnectionString,
CommandType.StoredProcedure,
stroredProcedure,
new SqlParameter("@DomainId", domainId),
new SqlParameter("@Date", date)
);
}
#endregion

View file

@ -0,0 +1,137 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using WebsitePanel.Providers.DomainLookup;
using Whois.NET;
namespace WebsitePanel.EnterpriseServer
{
public class DomainExpirationTask: SchedulerTask
{
private static readonly string TaskId = "SCHEDULE_TASK_DOMAIN_EXPIRATION";
// Input parameters:
private static readonly string DaysBeforeNotify = "DAYS_BEFORE";
private static readonly string MailToParameter = "MAIL_TO";
private static readonly string EnableNotification = "ENABLE_NOTIFICATION";
private static readonly string MailBodyTemplateParameter = "MAIL_BODY";
private static readonly string MailBodyDomainRecordTemplateParameter = "MAIL_DOMAIN_RECORD";
public override void DoWork()
{
BackgroundTask topTask = TaskManager.TopTask;
var domainUsers = new Dictionary<int, UserInfo>();
// get input parameters
int daysBeforeNotify;
bool sendEmailNotifcation = Convert.ToBoolean( topTask.GetParamValue(EnableNotification));
// check input parameters
if (String.IsNullOrEmpty((string)topTask.GetParamValue("MAIL_TO")))
{
TaskManager.WriteWarning("The e-mail message has not been sent because 'Mail To' is empty.");
return;
}
int.TryParse((string)topTask.GetParamValue(DaysBeforeNotify), out daysBeforeNotify);
var user = UserController.GetUser(topTask.EffectiveUserId);
var packages = GetUserPackages(user.UserId, user.Role);
var expiredDomains = new List<DomainInfo>();
foreach (var package in packages)
{
var domains = ServerController.GetDomains(package.PackageId);
domains = domains.Where(x => !x.IsSubDomain && !x.IsDomainPointer).ToList(); //Selecting top-level domains
domains = domains.Where(x => x.CreationDate == null || x.ExpirationDate == null ? true : CheckDomainExpiration(x.ExpirationDate, daysBeforeNotify)).ToList(); // selecting expired or with empty expire date domains
var domainUser = UserController.GetUser(package.UserId);
if (!domainUsers.ContainsKey(package.PackageId))
{
domainUsers.Add(package.PackageId, domainUser);
}
foreach (var domain in domains)
{
ServerController.UpdateDomainRegistrationData(domain);
if (CheckDomainExpiration(domain.ExpirationDate, daysBeforeNotify))
{
expiredDomains.Add(domain);
}
}
}
expiredDomains = expiredDomains.GroupBy(p => p.DomainId).Select(g => g.First()).ToList();
if (expiredDomains.Count > 0 && sendEmailNotifcation)
{
SendMailMessage(user, expiredDomains, domainUsers);
}
}
private IEnumerable<PackageInfo> GetUserPackages(int userId,UserRole userRole)
{
var packages = new List<PackageInfo>();
switch (userRole)
{
case UserRole.Administrator:
{
packages = ObjectUtils.CreateListFromDataReader<PackageInfo>(DataProvider.GetAllPackages());
break;
}
default:
{
packages = PackageController.GetMyPackages(userId);
break;
}
}
return packages;
}
private bool CheckDomainExpiration(DateTime? date, int daysBeforeNotify)
{
if (date == null)
{
return false;
}
return (date.Value - DateTime.Now).Days < daysBeforeNotify;
}
private void SendMailMessage(UserInfo user, IEnumerable<DomainInfo> domains, Dictionary<int, UserInfo> domainUsers)
{
BackgroundTask topTask = TaskManager.TopTask;
var bodyTemplate = ObjectUtils.FillObjectFromDataReader<ScheduleTaskEmailTemplate>(DataProvider.GetScheduleTaskEmailTemplate(TaskId, MailBodyTemplateParameter));
// input parameters
string mailFrom = "wsp-scheduler@noreply.net";
string mailTo = (string)topTask.GetParamValue("MAIL_TO");
string mailSubject = "Domain expiration notification";
Hashtable items = new Hashtable();
items["user"] = user;
items["Domains"] = domains.Select(x => new { DomainName = x.DomainName, ExpirationDate = x.ExpirationDate, Customer = string.Format("{0} {1}", domainUsers[x.PackageId].FirstName, domainUsers[x.PackageId].LastName) });
var mailBody = PackageController.EvaluateTemplate(bodyTemplate.Value, items);
// send mail message
MailHelper.SendMessage(mailFrom, mailTo, mailSubject, mailBody, true);
}
}
}

View file

@ -36,7 +36,7 @@ namespace WebsitePanel.EnterpriseServer
var dnsServers = dnsServersString.Split(';');
var packages = ObjectUtils.CreateListFromDataReader<PackageInfo>(DataProvider.GetAllPackagesIds());
var packages = ObjectUtils.CreateListFromDataReader<PackageInfo>(DataProvider.GetAllPackages());
foreach (var package in packages)
{

View file

@ -39,6 +39,8 @@ using WebsitePanel.Server;
using WebsitePanel.Providers.ResultObjects;
using WebsitePanel.Providers.Web;
using WebsitePanel.Providers.HostedSolution;
using Whois.NET;
using System.Text.RegularExpressions;
namespace WebsitePanel.EnterpriseServer
{
@ -49,6 +51,24 @@ namespace WebsitePanel.EnterpriseServer
{
private const string LOG_SOURCE_SERVERS = "SERVERS";
private static List<string> _createdDatePatterns = new List<string> { @"Creation Date:(.+)", // base
@"created:(.+)",
@"Created On:(.+)",
@"Domain Registration Date:(.+)",
@"Domain Create Date:(.+)",
@"Registered on:(.+)"};
private static List<string> _expiredDatePatterns = new List<string> { @"Expiration Date:(.+)", // base
@"Registry Expiry Date:(.+)", //.org
@"paid-till:(.+)", //.ru
@"Expires On:(.+)", //.name
@"Domain Expiration Date:(.+)", //.us
@"renewal date:(.+)", //.pl
@"Expiry date:(.+)", //.uk
@"anniversary:(.+)", //.fr
@"expires:(.+)" //.fi
};
#region Servers
public static List<ServerInfo> GetAllServers()
{
@ -1787,6 +1807,8 @@ namespace WebsitePanel.EnterpriseServer
ServerController.AddServiceDNSRecords(packageId, ResourceGroups.VPS, domain, "");
ServerController.AddServiceDNSRecords(packageId, ResourceGroups.VPSForPC, domain, "");
}
UpdateDomainRegistrationData(domain);
}
// add instant alias
@ -2637,6 +2659,47 @@ namespace WebsitePanel.EnterpriseServer
TaskManager.CompleteTask();
}
}
public static DomainInfo UpdateDomainRegistrationData(DomainInfo domain)
{
var whoisResult = WhoisClient.Query(domain.DomainName);
var createdDate = GetDomainInfoDate(whoisResult.Raw, _createdDatePatterns);
var expiredDate = GetDomainInfoDate(whoisResult.Raw, _expiredDatePatterns);
if (createdDate != null)
{
domain.CreationDate = createdDate;
DataProvider.UpdateDomainCreationDate(domain.DomainId, createdDate.Value);
}
if (expiredDate != null)
{
domain.ExpirationDate = expiredDate;
DataProvider.UpdateDomainExpirationDate(domain.DomainId, expiredDate.Value);
}
return domain;
}
private static DateTime? GetDomainInfoDate(string raw, IEnumerable<string> patterns)
{
foreach (var createdRegex in patterns)
{
var regex = new Regex(createdRegex, RegexOptions.IgnoreCase);
foreach (Match match in regex.Matches(raw))
{
if (match.Success && match.Groups.Count == 2)
{
return DateTime.Parse(match.Groups[1].ToString().Trim());
}
}
}
return null;
}
#endregion
#region DNS Zones

View file

@ -35,6 +35,9 @@
<Reference Include="Ionic.Zip.Reduced">
<HintPath>..\..\Lib\Ionic.Zip.Reduced.dll</HintPath>
</Reference>
<Reference Include="IPAddressRange">
<HintPath>..\..\Lib\References\Whois.NET\IPAddressRange.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Web.Services3">
<HintPath>..\..\Lib\Microsoft.Web.Services3.dll</HintPath>
<Private>True</Private>
@ -62,6 +65,9 @@
<Reference Include="WebsitePanel.Server.Client">
<HintPath>..\..\Bin\WebsitePanel.Server.Client.dll</HintPath>
</Reference>
<Reference Include="WhoisClient">
<HintPath>..\..\Lib\References\Whois.NET\WhoisClient.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Comments\CommentsController.cs" />
@ -140,6 +146,7 @@
<Compile Include="SchedulerTasks\CalculatePackagesDiskspaceTask.cs" />
<Compile Include="SchedulerTasks\CancelOverdueInvoicesTask.cs" />
<Compile Include="SchedulerTasks\CheckWebSiteTask.cs" />
<Compile Include="SchedulerTasks\DomainExpirationTask.cs" />
<Compile Include="SchedulerTasks\FTPFilesTask.cs" />
<Compile Include="SchedulerTasks\GenerateInvoicesTask.cs" />
<Compile Include="SchedulerTasks\HostedSolutionReport.cs" />

View file

@ -5596,4 +5596,7 @@
<data name="SchedulerTask.SCHEDULE_TASK_DOMAIN_LOOKUP" xml:space="preserve">
<value>Check MX and NS on DNS servers</value>
</data>
<data name="SchedulerTask.SCHEDULE_TASK_DOMAIN_EXPIRATION" xml:space="preserve">
<value>Check domain expiration date</value>
</data>
</root>

View file

@ -112,10 +112,10 @@
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<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=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ModuleAction.AddDomain" xml:space="preserve">
<value>Add New Domain</value>
@ -198,4 +198,13 @@
<data name="gvDomainsType.Header" xml:space="preserve">
<value>Type</value>
</data>
<data name="DomainExpirationDate.Expired" xml:space="preserve">
<value>Expired</value>
</data>
<data name="DomainExpirationDate.Unknown" xml:space="preserve">
<value>Unknown</value>
</data>
<data name="gvDomainsExpirationDate.Header" xml:space="preserve">
<value>Expiration Date</value>
</data>
</root>

View file

@ -25,7 +25,7 @@
CssSelectorClass="NormalGridView" AllowPaging="True" OnRowCommand="gvDomains_RowCommand">
<Columns>
<asp:TemplateField SortExpression="DomainName" HeaderText="gvDomainsName">
<ItemStyle Width="60%" Wrap="False"></ItemStyle>
<ItemStyle Width="45%" Wrap="False"></ItemStyle>
<ItemTemplate>
<b><asp:hyperlink id=lnkEdit1 runat="server" CssClass="Medium"
NavigateUrl='<%# GetItemEditUrl(Eval("PackageID"), Eval("DomainID")) %>'>
@ -37,6 +37,12 @@
</div>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="gvDomainsExpirationDate">
<ItemStyle Width="15%"></ItemStyle>
<ItemTemplate>
<%# GetDomainExpirationDate(Eval("ExpirationDate"))%>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="gvDomainsType">
<ItemStyle Width="30%"></ItemStyle>
<ItemTemplate>

View file

@ -49,10 +49,10 @@ namespace WebsitePanel.Portal
// visibility
chkRecursive.Visible = (PanelSecurity.SelectedUser.Role != UserRole.User);
gvDomains.Columns[2].Visible = gvDomains.Columns[3].Visible =
gvDomains.Columns[3].Visible = gvDomains.Columns[3].Visible =
(PanelSecurity.SelectedUser.Role != UserRole.User) && chkRecursive.Checked;
gvDomains.Columns[4].Visible = (PanelSecurity.SelectedUser.Role == UserRole.Administrator);
gvDomains.Columns[5].Visible = (PanelSecurity.EffectiveUser.Role == UserRole.Administrator);
gvDomains.Columns[5].Visible = (PanelSecurity.SelectedUser.Role == UserRole.Administrator);
gvDomains.Columns[6].Visible = (PanelSecurity.EffectiveUser.Role == UserRole.Administrator);
if (!IsPostBack)
{
@ -100,6 +100,18 @@ namespace WebsitePanel.Portal
return GetLocalizedString("DomainType.Domain");
}
public string GetDomainExpirationDate(object expirationDateObject)
{
var expirationDate = expirationDateObject as DateTime?;
if (expirationDate == null)
return GetLocalizedString("DomainExpirationDate.Unknown");
else if (expirationDate < DateTime.Now)
return GetLocalizedString("DomainExpirationDate.Expired");
else
return expirationDate.Value.ToShortDateString();
}
protected void odsDomainsPaged_Selected(object sender, ObjectDataSourceStatusEventArgs e)
{
if (e.Exception != null)

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.

View file

@ -0,0 +1,129 @@
<?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="cbEnableNotify" xml:space="preserve">
<value>Enable Client Notification</value>
</data>
<data name="lblDayBeforeNotify" xml:space="preserve">
<value>Notify before</value>
</data>
<data name="lblDayBeforeNotifyHint" xml:space="preserve">
<value>Number of days before expiration date</value>
</data>
</root>

View file

@ -0,0 +1,31 @@
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="DomainExpirationView.ascx.cs" Inherits="WebsitePanel.Portal.ScheduleTaskControls.DomainExpirationView" %>
<table cellspacing="0" cellpadding="4" width="100%">
<tr>
<td class="SubHead" nowrap>
<asp:Label ID="Label1" runat="server" meta:resourcekey="cbEnableNotify" Text="Enable Client Notification:"></asp:Label>
</td>
<td>
<asp:CheckBox runat="server" ID="cbEnableNotify" meta:resourcekey="cbEnableNotify" /><br/>
</td>
</tr>
<tr>
<td class="SubHead" nowrap>
<asp:Label ID="lblMailTo" runat="server" meta:resourcekey="lblMailTo" Text="Mail To:"></asp:Label>
</td>
<td class="Normal" width="100%">
<asp:TextBox ID="txtMailTo" runat="server" Width="95%" CssClass="NormalTextBox" MaxLength="1000"></asp:TextBox>
</td>
</tr>
<tr>
<td class="SubHead" nowrap>
<asp:Label ID="lblDayBeforeNotify" runat="server" meta:resourcekey="lblDayBeforeNotify" Text="Notify before:"></asp:Label>
</td>
<td class="Normal" width="100%">
<asp:TextBox ID="txtDaysBeforeNotify" runat="server" Width="95%" CssClass="NormalTextBox" MaxLength="1000"></asp:TextBox><br />
<asp:Label ID="lblDayBeforeNotifyHint" runat="server" meta:resourcekey="lblDayBeforeNotifyHint" Text="Number of days before expiration date"></asp:Label>
</td>
</tr>
</table>

View file

@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using WebsitePanel.EnterpriseServer;
using WebsitePanel.Portal.UserControls.ScheduleTaskView;
namespace WebsitePanel.Portal.ScheduleTaskControls
{
public partial class DomainExpirationView : EmptyView
{
private static readonly string DaysBeforeParameter = "DAYS_BEFORE";
private static readonly string MailToParameter = "MAIL_TO";
private static readonly string EnableNotificationParameter = "ENABLE_NOTIFICATION";
protected void Page_Load(object sender, EventArgs e)
{
}
/// <summary>
/// Sets scheduler task parameters on view.
/// </summary>
/// <param name="parameters">Parameters list to be set on view.</param>
public override void SetParameters(ScheduleTaskParameterInfo[] parameters)
{
base.SetParameters(parameters);
this.SetParameter(this.txtDaysBeforeNotify, DaysBeforeParameter);
this.SetParameter(this.txtMailTo, MailToParameter);
this.SetParameter(this.cbEnableNotify, EnableNotificationParameter);
}
/// <summary>
/// Gets scheduler task parameters from view.
/// </summary>
/// <returns>Parameters list filled from view.</returns>
public override ScheduleTaskParameterInfo[] GetParameters()
{
ScheduleTaskParameterInfo daysBefore = this.GetParameter(this.txtDaysBeforeNotify, DaysBeforeParameter);
ScheduleTaskParameterInfo mailTo = this.GetParameter(this.txtMailTo, MailToParameter);
ScheduleTaskParameterInfo enableNotification = this.GetParameter(this.cbEnableNotify, EnableNotificationParameter);
return new ScheduleTaskParameterInfo[3] { daysBefore, mailTo, enableNotification };
}
}
}

View file

@ -0,0 +1,78 @@
//------------------------------------------------------------------------------
// <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.ScheduleTaskControls {
public partial class DomainExpirationView {
/// <summary>
/// Label1 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.Label Label1;
/// <summary>
/// cbEnableNotify 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.CheckBox cbEnableNotify;
/// <summary>
/// lblMailTo 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.Label lblMailTo;
/// <summary>
/// txtMailTo 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 txtMailTo;
/// <summary>
/// lblDayBeforeNotify 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.Label lblDayBeforeNotify;
/// <summary>
/// txtDaysBeforeNotify 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 txtDaysBeforeNotify;
/// <summary>
/// lblDayBeforeNotifyHint 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.Label lblDayBeforeNotifyHint;
}
}

View file

@ -15,5 +15,6 @@
</td>
<td class="Normal" width="100%">
<asp:TextBox ID="txtMailTo" runat="server" Width="95%" CssClass="NormalTextBox" MaxLength="1000"></asp:TextBox>
</td>
</tr>
</table>

View file

@ -293,6 +293,13 @@
<DesignTime>True</DesignTime>
<DependentUpon>DomainLookupView.ascx.resx</DependentUpon>
</Compile>
<Compile Include="ScheduleTaskControls\DomainExpirationView.ascx.cs">
<DependentUpon>DomainExpirationView.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="ScheduleTaskControls\DomainExpirationView.ascx.designer.cs">
<DependentUpon>DomainExpirationView.ascx</DependentUpon>
</Compile>
<Compile Include="ScheduleTaskControls\DomainLookupView.ascx.cs">
<DependentUpon>DomainLookupView.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
@ -4246,10 +4253,12 @@
<Content Include="RDS\UserControls\RDSCollectionApps.ascx" />
<Content Include="RDS\UserControls\RDSCollectionServers.ascx" />
<Content Include="RDS\UserControls\RDSCollectionUsers.ascx" />
<Content Include="ScheduleTaskControls\App_LocalResources\DomainExpirationView.ascx.resx" />
<EmbeddedResource Include="ScheduleTaskControls\App_LocalResources\DomainLookupView.ascx.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>DomainLookupView.ascx.Designer.cs</LastGenOutput>
</EmbeddedResource>
<Content Include="ScheduleTaskControls\DomainExpirationView.ascx" />
<Content Include="ScheduleTaskControls\DomainLookupView.ascx" />
<Content Include="SettingsServiceLevels.ascx" />
<Content Include="CRM\CRMStorageSettings.ascx" />