diff --git a/WebsitePanel/Database/install_db.sql b/WebsitePanel/Database/install_db.sql
index a60cc0d3..db6d20f7 100644
--- a/WebsitePanel/Database/install_db.sql
+++ b/WebsitePanel/Database/install_db.sql
@@ -667,6 +667,8 @@ CREATE TABLE [dbo].[Users](
[CompanyName] [nvarchar](100) COLLATE Latin1_General_CI_AS NULL,
[EcommerceEnabled] [bit] NULL,
[AdditionalParams] [nvarchar](max) COLLATE Latin1_General_CI_AS NULL,
+ [LoginStatusId] [int] NULL,
+ [FailedLogins] [int] NULL,
CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED
(
[UserID] ASC
@@ -9749,7 +9751,7 @@ GO
CREATE VIEW [dbo].[UsersDetailed]
AS
-SELECT U.UserID, U.RoleID, U.StatusID, U.OwnerID, U.Created, U.Changed, U.IsDemo, U.Comments, U.IsPeer, U.Username, U.FirstName, U.LastName, U.Email,
+SELECT U.UserID, U.RoleID, U.StatusID, U.LoginStatusId, U.FailedLogins, U.OwnerID, U.Created, U.Changed, U.IsDemo, U.Comments, U.IsPeer, U.Username, U.FirstName, U.LastName, U.Email,
U.CompanyName, U.FirstName + ' ' + U.LastName AS FullName, UP.Username AS OwnerUsername, UP.FirstName AS OwnerFirstName,
UP.LastName AS OwnerLastName, UP.RoleID AS OwnerRoleID, UP.FirstName + ' ' + UP.LastName AS OwnerFullName, UP.Email AS OwnerEmail, UP.RoleID AS Expr1,
(SELECT COUNT(PackageID) AS Expr1
@@ -11983,6 +11985,8 @@ SELECT
U.UserID,
U.RoleID,
U.StatusID,
+ U.LoginStatusId,
+ U.FailedLogins,
U.OwnerID,
U.Created,
U.Changed,
@@ -12048,6 +12052,7 @@ RETURN
+
GO
@@ -12085,7 +12090,7 @@ GO
-CREATE PROCEDURE GetUserDomainsPaged
+CREATE PROCEDURE [dbo].[GetUserDomainsPaged]
(
@ActorID int,
@UserID int,
@@ -12134,6 +12139,8 @@ SELECT
U.UserID,
U.RoleID,
U.StatusID,
+ U.LoginStatusId,
+ U.FailedLogins,
U.OwnerID,
U.Created,
U.Changed,
@@ -12187,7 +12194,6 @@ RETURN
-
GO
@@ -19490,6 +19496,8 @@ AS
U.UserID,
U.RoleID,
U.StatusID,
+ U.LoginStatusId,
+ U.FailedLogins,
U.OwnerID,
U.Created,
U.Changed,
@@ -19536,6 +19544,8 @@ AS
U.UserID,
U.RoleID,
U.StatusID,
+ U.LoginStatusId,
+ U.FailedLogins,
U.OwnerID,
U.Created,
U.Changed,
@@ -19897,6 +19907,8 @@ SELECT
U.UserID,
U.RoleID,
U.StatusID,
+ U.LoginStatusId,
+ U.FailedLogins,
U.OwnerID,
U.Created,
U.Changed,
@@ -19923,7 +19935,7 @@ WHERE U.UserID <> @OwnerID AND
AND U.IsPeer = 0
AND @CanGetDetails = 1 -- actor user rights
-RETURN
+RETURN
@@ -20015,6 +20027,8 @@ SELECT
U.UserID,
U.RoleID,
U.StatusID,
+ U.LoginStatusId,
+ U.FailedLogins,
U.OwnerID,
U.Created,
U.Changed,
@@ -25166,6 +25180,7 @@ CREATE PROCEDURE [dbo].[AddUser]
@OwnerID int,
@RoleID int,
@StatusID int,
+ @LoginStatusID int,
@IsDemo bit,
@IsPeer bit,
@Comments ntext,
@@ -25209,6 +25224,7 @@ INSERT INTO Users
OwnerID,
RoleID,
StatusID,
+ LoginStatusID,
Created,
Changed,
IsDemo,
@@ -25238,6 +25254,7 @@ VALUES
@OwnerID,
@RoleID,
@StatusID,
+ @LoginStatusID,
GetDate(),
GetDate(),
@IsDemo,
@@ -25265,8 +25282,7 @@ VALUES
SET @UserID = SCOPE_IDENTITY()
-RETURN
-
+RETURN
@@ -25444,6 +25460,7 @@ CREATE PROCEDURE [dbo].[UpdateUser]
@UserID int,
@RoleID int,
@StatusID int,
+ @LoginStatusId int,
@IsDemo bit,
@IsPeer bit,
@Comments ntext,
@@ -25473,9 +25490,17 @@ AS
RETURN
END
+ IF @LoginStatusId = 0
+ BEGIN
+ UPDATE Users SET
+ FailedLogins = 0
+ WHERE UserID = @UserID
+ END
+
UPDATE Users SET
RoleID = @RoleID,
StatusID = @StatusID,
+ LoginStatusId = @LoginStatusId,
Changed = GetDate(),
IsDemo = @IsDemo,
IsPeer = @IsPeer,
@@ -25522,17 +25547,44 @@ GO
+CREATE PROCEDURE [dbo].[UpdateUserFailedLoginAttempt]
+(
+ @UserID int,
+ @LockOut int,
+ @Reset int
+)
+AS
+
+IF (@Reset = 1)
+BEGIN
+ UPDATE Users SET FailedLogins = 0 WHERE UserID = @UserID
+END
+ELSE
+BEGIN
+ IF (@LockOut <= (SELECT FailedLogins FROM USERS WHERE UserID = @UserID))
+ BEGIN
+ UPDATE Users SET LoginStatusId = 2 WHERE UserID = @UserID
+ END
+ ELSE
+ BEGIN
+ IF ((SELECT FailedLogins FROM Users WHERE UserID = @UserID) IS NULL)
+ BEGIN
+ UPDATE Users SET FailedLogins = 1 WHERE UserID = @UserID
+ END
+ ELSE
+ UPDATE Users SET FailedLogins = FailedLogins + 1 WHERE UserID = @UserID
+ END
+END
-
-
-
-
-
-
+GO
+SET ANSI_NULLS ON
+GO
+SET QUOTED_IDENTIFIER ON
+GO
CREATE PROCEDURE DeleteComment
@@ -28695,6 +28747,8 @@ SELECT
U.UserID,
U.RoleID,
U.StatusID,
+ U.LoginStatusId,
+ U.FailedLogins,
U.OwnerID,
U.Created,
U.Changed,
@@ -28861,6 +28915,8 @@ AS
U.UserID,
U.RoleID,
U.StatusID,
+ U.LoginStatusId,
+ U.FailedLogins,
U.OwnerID,
U.Created,
U.Changed,
@@ -28912,6 +28968,8 @@ AS
U.UserID,
U.RoleID,
U.StatusID,
+ U.LoginStatusId,
+ U.FailedLogins,
U.OwnerID,
U.Created,
U.Changed,
diff --git a/WebsitePanel/Database/update_db.sql b/WebsitePanel/Database/update_db.sql
index f838087e..aeb27458 100644
--- a/WebsitePanel/Database/update_db.sql
+++ b/WebsitePanel/Database/update_db.sql
@@ -1009,6 +1009,15 @@ END
GO
+IF NOT EXISTS(select 1 from sys.columns COLS INNER JOIN sys.objects OBJS ON OBJS.object_id=COLS.object_id and OBJS.type='U' AND OBJS.name='Users' AND COLS.name='LoginStatusId')
+BEGIN
+ALTER TABLE [dbo].[Users] ADD
+ [LoginStatusId] [int] NULL,
+ [FailedLogins] [int] NULL
+END
+GO
+
+
IF NOT EXISTS(select 1 from sys.columns COLS INNER JOIN sys.objects OBJS ON OBJS.object_id=COLS.object_id and OBJS.type='U' AND OBJS.name='GlobalDnsRecords' AND COLS.name='SrvPriority')
BEGIN
ALTER TABLE [dbo].[GlobalDnsRecords] ADD
@@ -1028,6 +1037,19 @@ UPDATE [dbo].[ResourceGroups] SET ShowGroup=1
GO
+ALTER VIEW [dbo].[UsersDetailed]
+AS
+SELECT U.UserID, U.RoleID, U.StatusID, U.LoginStatusId, U.FailedLogins, U.OwnerID, U.Created, U.Changed, U.IsDemo, U.Comments, U.IsPeer, U.Username, U.FirstName, U.LastName, U.Email,
+ U.CompanyName, U.FirstName + ' ' + U.LastName AS FullName, UP.Username AS OwnerUsername, UP.FirstName AS OwnerFirstName,
+ UP.LastName AS OwnerLastName, UP.RoleID AS OwnerRoleID, UP.FirstName + ' ' + UP.LastName AS OwnerFullName, UP.Email AS OwnerEmail, UP.RoleID AS Expr1,
+ (SELECT COUNT(PackageID) AS Expr1
+ FROM dbo.Packages AS P
+ WHERE (UserID = U.UserID)) AS PackagesNumber, U.EcommerceEnabled
+FROM dbo.Users AS U LEFT OUTER JOIN
+ dbo.Users AS UP ON U.OwnerID = UP.UserID
+GO
+
+
ALTER PROCEDURE [dbo].[AddDnsRecord]
(
@ActorID int,
@@ -2031,6 +2053,13 @@ IF ((SELECT Count(*) FROM ExchangeMailboxPlans WHERE ItemId = @ItemID) = 0)
BEGIN
SET @IsDefault = 1
END
+ELSE
+BEGIN
+ IF @IsDefault = 1
+ BEGIN
+ UPDATE ExchangeMailboxPlans SET IsDefault = 0 WHERE ItemID = @ItemID
+ END
+END
INSERT INTO ExchangeMailboxPlans
(
@@ -3920,6 +3949,169 @@ GO
+ALTER PROCEDURE [dbo].[AddUser]
+(
+ @ActorID int,
+ @UserID int OUTPUT,
+ @OwnerID int,
+ @RoleID int,
+ @StatusID int,
+ @LoginStatusID int,
+ @IsDemo bit,
+ @IsPeer bit,
+ @Comments ntext,
+ @Username nvarchar(50),
+ @Password nvarchar(200),
+ @FirstName nvarchar(50),
+ @LastName nvarchar(50),
+ @Email nvarchar(255),
+ @SecondaryEmail nvarchar(255),
+ @Address nvarchar(200),
+ @City nvarchar(50),
+ @State nvarchar(50),
+ @Country nvarchar(50),
+ @Zip varchar(20),
+ @PrimaryPhone varchar(30),
+ @SecondaryPhone varchar(30),
+ @Fax varchar(30),
+ @InstantMessenger nvarchar(200),
+ @HtmlMail bit,
+ @CompanyName nvarchar(100),
+ @EcommerceEnabled bit
+)
+AS
+
+-- check if the user already exists
+IF EXISTS(SELECT UserID FROM Users WHERE Username = @Username)
+BEGIN
+ SET @UserID = -1
+ RETURN
+END
+
+-- check actor rights
+IF dbo.CanCreateUser(@ActorID, @OwnerID) = 0
+BEGIN
+ SET @UserID = -2
+ RETURN
+END
+
+INSERT INTO Users
+(
+ OwnerID,
+ RoleID,
+ StatusID,
+ LoginStatusID,
+ Created,
+ Changed,
+ IsDemo,
+ IsPeer,
+ Comments,
+ Username,
+ Password,
+ FirstName,
+ LastName,
+ Email,
+ SecondaryEmail,
+ Address,
+ City,
+ State,
+ Country,
+ Zip,
+ PrimaryPhone,
+ SecondaryPhone,
+ Fax,
+ InstantMessenger,
+ HtmlMail,
+ CompanyName,
+ EcommerceEnabled
+)
+VALUES
+(
+ @OwnerID,
+ @RoleID,
+ @StatusID,
+ @LoginStatusID,
+ GetDate(),
+ GetDate(),
+ @IsDemo,
+ @IsPeer,
+ @Comments,
+ @Username,
+ @Password,
+ @FirstName,
+ @LastName,
+ @Email,
+ @SecondaryEmail,
+ @Address,
+ @City,
+ @State,
+ @Country,
+ @Zip,
+ @PrimaryPhone,
+ @SecondaryPhone,
+ @Fax,
+ @InstantMessenger,
+ @HtmlMail,
+ @CompanyName,
+ @EcommerceEnabled
+)
+
+SET @UserID = SCOPE_IDENTITY()
+
+RETURN
+GO
+
+
+
+
+
+
+ALTER PROCEDURE [dbo].[GetUserById]
+(
+ @ActorID int,
+ @UserID int
+)
+AS
+ -- user can retrieve his own account, his users accounts
+ -- and his reseller account (without pasword)
+ SELECT
+ U.UserID,
+ U.RoleID,
+ U.StatusID,
+ U.LoginStatusId,
+ U.FailedLogins,
+ U.OwnerID,
+ U.Created,
+ U.Changed,
+ U.IsDemo,
+ U.Comments,
+ U.IsPeer,
+ U.Username,
+ CASE WHEN dbo.CanGetUserPassword(@ActorID, @UserID) = 1 THEN U.Password
+ ELSE '' END AS Password,
+ U.FirstName,
+ U.LastName,
+ U.Email,
+ U.SecondaryEmail,
+ U.Address,
+ U.City,
+ U.State,
+ U.Country,
+ U.Zip,
+ U.PrimaryPhone,
+ U.SecondaryPhone,
+ U.Fax,
+ U.InstantMessenger,
+ U.HtmlMail,
+ U.CompanyName,
+ U.EcommerceEnabled,
+ U.[AdditionalParams]
+ FROM Users AS U
+ WHERE U.UserID = @UserID
+ AND dbo.CanGetUserDetails(@ActorID, @UserID) = 1 -- actor user rights
+
+ RETURN
+GO
@@ -3931,3 +4123,608 @@ GO
+
+
+ALTER PROCEDURE [dbo].[GetUserByIdInternally]
+(
+ @UserID int
+)
+AS
+ SELECT
+ U.UserID,
+ U.RoleID,
+ U.StatusID,
+ U.LoginStatusId,
+ U.FailedLogins,
+ U.OwnerID,
+ U.Created,
+ U.Changed,
+ U.IsDemo,
+ U.Comments,
+ U.IsPeer,
+ U.Username,
+ U.Password,
+ U.FirstName,
+ U.LastName,
+ U.Email,
+ U.SecondaryEmail,
+ U.Address,
+ U.City,
+ U.State,
+ U.Country,
+ U.Zip,
+ U.PrimaryPhone,
+ U.SecondaryPhone,
+ U.Fax,
+ U.InstantMessenger,
+ U.HtmlMail,
+ U.CompanyName,
+ U.EcommerceEnabled,
+ U.[AdditionalParams]
+ FROM Users AS U
+ WHERE U.UserID = @UserID
+
+ RETURN
+
+GO
+
+
+
+
+
+
+
+
+
+
+ALTER PROCEDURE [dbo].[GetUserByUsername]
+(
+ @ActorID int,
+ @Username nvarchar(50)
+)
+AS
+
+ SELECT
+ U.UserID,
+ U.RoleID,
+ U.StatusID,
+ U.LoginStatusId,
+ U.FailedLogins,
+ U.OwnerID,
+ U.Created,
+ U.Changed,
+ U.IsDemo,
+ U.Comments,
+ U.IsPeer,
+ U.Username,
+ CASE WHEN dbo.CanGetUserPassword(@ActorID, UserID) = 1 THEN U.Password
+ ELSE '' END AS Password,
+ U.FirstName,
+ U.LastName,
+ U.Email,
+ U.SecondaryEmail,
+ U.Address,
+ U.City,
+ U.State,
+ U.Country,
+ U.Zip,
+ U.PrimaryPhone,
+ U.SecondaryPhone,
+ U.Fax,
+ U.InstantMessenger,
+ U.HtmlMail,
+ U.CompanyName,
+ U.EcommerceEnabled,
+ U.[AdditionalParams]
+ FROM Users AS U
+ WHERE U.Username = @Username
+ AND dbo.CanGetUserDetails(@ActorID, UserID) = 1 -- actor user rights
+
+ RETURN
+GO
+
+
+
+
+
+
+
+
+ALTER PROCEDURE [dbo].[GetUserByUsernameInternally]
+(
+ @Username nvarchar(50)
+)
+AS
+ SELECT
+ U.UserID,
+ U.RoleID,
+ U.StatusID,
+ U.LoginStatusId,
+ U.FailedLogins,
+ U.OwnerID,
+ U.Created,
+ U.Changed,
+ U.IsDemo,
+ U.Comments,
+ U.IsPeer,
+ U.Username,
+ U.Password,
+ U.FirstName,
+ U.LastName,
+ U.Email,
+ U.SecondaryEmail,
+ U.Address,
+ U.City,
+ U.State,
+ U.Country,
+ U.Zip,
+ U.PrimaryPhone,
+ U.SecondaryPhone,
+ U.Fax,
+ U.InstantMessenger,
+ U.HtmlMail,
+ U.CompanyName,
+ U.EcommerceEnabled,
+ U.[AdditionalParams]
+ FROM Users AS U
+ WHERE U.Username = @Username
+
+ RETURN
+
+GO
+
+
+
+
+
+
+
+
+
+
+
+
+
+ALTER PROCEDURE [dbo].[GetUserDomainsPaged]
+(
+ @ActorID int,
+ @UserID int,
+ @FilterColumn nvarchar(50) = '',
+ @FilterValue nvarchar(50) = '',
+ @SortColumn nvarchar(50),
+ @StartRow int,
+ @MaximumRows int
+)
+AS
+-- build query and run it to the temporary table
+DECLARE @sql nvarchar(2000)
+
+SET @sql = '
+DECLARE @HasUserRights bit
+SET @HasUserRights = dbo.CheckActorUserRights(@ActorID, @UserID)
+
+DECLARE @EndRow int
+SET @EndRow = @StartRow + @MaximumRows
+DECLARE @Users TABLE
+(
+ ItemPosition int IDENTITY(1,1),
+ UserID int,
+ DomainID int
+)
+INSERT INTO @Users (UserID, DomainID)
+SELECT
+ U.UserID,
+ D.DomainID
+FROM Users AS U
+INNER JOIN UsersTree(@UserID, 1) AS UT ON U.UserID = UT.UserID
+LEFT OUTER JOIN Packages AS P ON U.UserID = P.UserID
+LEFT OUTER JOIN Domains AS D ON P.PackageID = D.PackageID
+WHERE
+ U.UserID <> @UserID AND U.IsPeer = 0
+ AND @HasUserRights = 1 '
+
+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(UserID) FROM @Users;
+SELECT
+ U.UserID,
+ U.RoleID,
+ U.StatusID,
+ U.LoginStatusId,
+ U.FailedLogins,
+ U.OwnerID,
+ U.Created,
+ U.Changed,
+ U.IsDemo,
+ U.Comments,
+ U.IsPeer,
+ U.Username,
+ U.FirstName,
+ U.LastName,
+ U.Email,
+ D.DomainName
+FROM @Users AS TU
+INNER JOIN Users AS U ON TU.UserID = U.UserID
+LEFT OUTER JOIN Domains AS D ON TU.DomainID = D.DomainID
+WHERE TU.ItemPosition BETWEEN @StartRow AND @EndRow'
+
+exec sp_executesql @sql, N'@StartRow int, @MaximumRows int, @UserID int, @FilterValue nvarchar(50), @ActorID int',
+@StartRow, @MaximumRows, @UserID, @FilterValue, @ActorID
+
+
+RETURN
+GO
+
+
+
+
+
+
+
+
+
+
+
+
+ALTER PROCEDURE [dbo].[GetUserParents]
+(
+ @ActorID int,
+ @UserID int
+)
+AS
+
+-- check rights
+IF dbo.CheckActorUserRights(@ActorID, @UserID) = 0
+RAISERROR('You are not allowed to access this account', 16, 1)
+
+SELECT
+ U.UserID,
+ U.RoleID,
+ U.StatusID,
+ U.LoginStatusId,
+ U.FailedLogins,
+ U.OwnerID,
+ U.Created,
+ U.Changed,
+ U.IsDemo,
+ U.Comments,
+ U.IsPeer,
+ U.Username,
+ U.FirstName,
+ U.LastName,
+ U.Email,
+ U.CompanyName,
+ U.EcommerceEnabled
+FROM UserParents(@ActorID, @UserID) AS UP
+INNER JOIN Users AS U ON UP.UserID = U.UserID
+ORDER BY UP.UserOrder DESC
+RETURN
+GO
+
+
+
+
+
+
+
+
+
+
+
+
+
+ALTER PROCEDURE [dbo].[GetUserPeers]
+(
+ @ActorID int,
+ @UserID int
+)
+AS
+
+DECLARE @CanGetDetails bit
+SET @CanGetDetails = dbo.CanGetUserDetails(@ActorID, @UserID)
+
+SELECT
+ U.UserID,
+ U.RoleID,
+ U.StatusID,
+ U.LoginStatusId,
+ U.FailedLogins,
+ U.OwnerID,
+ U.Created,
+ U.Changed,
+ U.IsDemo,
+ U.Comments,
+ U.IsPeer,
+ U.Username,
+ U.FirstName,
+ U.LastName,
+ U.Email,
+ U.FullName,
+ (U.FirstName + ' ' + U.LastName) AS FullName,
+ U.CompanyName,
+ U.EcommerceEnabled
+FROM UsersDetailed AS U
+WHERE U.OwnerID = @UserID AND IsPeer = 1
+AND @CanGetDetails = 1 -- actor rights
+
+RETURN
+GO
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ALTER PROCEDURE [dbo].[GetUsers]
+(
+ @ActorID int,
+ @OwnerID int,
+ @Recursive bit = 0
+)
+AS
+
+DECLARE @CanGetDetails bit
+SET @CanGetDetails = dbo.CanGetUserDetails(@ActorID, @OwnerID)
+
+SELECT
+ U.UserID,
+ U.RoleID,
+ U.StatusID,
+ U.LoginStatusId,
+ U.FailedLogins,
+ U.OwnerID,
+ U.Created,
+ U.Changed,
+ U.IsDemo,
+ U.Comments,
+ U.IsPeer,
+ U.Username,
+ U.FirstName,
+ U.LastName,
+ U.Email,
+ U.FullName,
+ U.OwnerUsername,
+ U.OwnerFirstName,
+ U.OwnerLastName,
+ U.OwnerRoleID,
+ U.OwnerFullName,
+ U.PackagesNumber,
+ U.CompanyName,
+ U.EcommerceEnabled
+FROM UsersDetailed AS U
+WHERE U.UserID <> @OwnerID AND
+((@Recursive = 1 AND dbo.CheckUserParent(@OwnerID, U.UserID) = 1) OR
+(@Recursive = 0 AND U.OwnerID = @OwnerID))
+AND U.IsPeer = 0
+AND @CanGetDetails = 1 -- actor user rights
+
+RETURN
+GO
+
+
+
+
+
+
+
+
+
+
+ALTER PROCEDURE [dbo].[GetUsersPaged]
+(
+ @ActorID int,
+ @UserID int,
+ @FilterColumn nvarchar(50) = '',
+ @FilterValue nvarchar(50) = '',
+ @StatusID int,
+ @RoleID int,
+ @SortColumn nvarchar(50),
+ @StartRow int,
+ @MaximumRows int,
+ @Recursive bit
+)
+AS
+-- build query and run it to the temporary table
+DECLARE @sql nvarchar(2000)
+
+SET @sql = '
+
+DECLARE @HasUserRights bit
+SET @HasUserRights = dbo.CheckActorUserRights(@ActorID, @UserID)
+
+DECLARE @EndRow int
+SET @EndRow = @StartRow + @MaximumRows
+DECLARE @Users TABLE
+(
+ ItemPosition int IDENTITY(0,1),
+ UserID int
+)
+INSERT INTO @Users (UserID)
+SELECT
+ U.UserID
+FROM UsersDetailed AS U
+WHERE
+ U.UserID <> @UserID AND U.IsPeer = 0 AND
+ (
+ (@Recursive = 0 AND OwnerID = @UserID) OR
+ (@Recursive = 1 AND dbo.CheckUserParent(@UserID, U.UserID) = 1)
+ )
+ AND ((@StatusID = 0) OR (@StatusID > 0 AND U.StatusID = @StatusID))
+ AND ((@RoleID = 0) OR (@RoleID > 0 AND U.RoleID = @RoleID))
+ AND @HasUserRights = 1 '
+
+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(UserID) FROM @Users;
+SELECT
+ U.UserID,
+ U.RoleID,
+ U.StatusID,
+ U.LoginStatusId,
+ U.FailedLogins,
+ U.OwnerID,
+ U.Created,
+ U.Changed,
+ U.IsDemo,
+ dbo.GetItemComments(U.UserID, ''USER'', @ActorID) AS Comments,
+ U.IsPeer,
+ U.Username,
+ U.FirstName,
+ U.LastName,
+ U.Email,
+ U.FullName,
+ U.OwnerUsername,
+ U.OwnerFirstName,
+ U.OwnerLastName,
+ U.OwnerRoleID,
+ U.OwnerFullName,
+ U.OwnerEmail,
+ U.PackagesNumber,
+ U.CompanyName,
+ U.EcommerceEnabled
+FROM @Users AS TU
+INNER JOIN UsersDetailed AS U ON TU.UserID = U.UserID
+WHERE TU.ItemPosition BETWEEN @StartRow AND @EndRow'
+
+exec sp_executesql @sql, N'@StartRow int, @MaximumRows int, @UserID int, @FilterValue nvarchar(50), @ActorID int, @Recursive bit, @StatusID int, @RoleID int',
+@StartRow, @MaximumRows, @UserID, @FilterValue, @ActorID, @Recursive, @StatusID, @RoleID
+
+
+RETURN
+GO
+
+
+
+
+
+
+
+
+ALTER PROCEDURE [dbo].[UpdateUser]
+(
+ @ActorID int,
+ @UserID int,
+ @RoleID int,
+ @StatusID int,
+ @LoginStatusId int,
+ @IsDemo bit,
+ @IsPeer bit,
+ @Comments ntext,
+ @FirstName nvarchar(50),
+ @LastName nvarchar(50),
+ @Email nvarchar(255),
+ @SecondaryEmail nvarchar(255),
+ @Address nvarchar(200),
+ @City nvarchar(50),
+ @State nvarchar(50),
+ @Country nvarchar(50),
+ @Zip varchar(20),
+ @PrimaryPhone varchar(30),
+ @SecondaryPhone varchar(30),
+ @Fax varchar(30),
+ @InstantMessenger nvarchar(200),
+ @HtmlMail bit,
+ @CompanyName nvarchar(100),
+ @EcommerceEnabled BIT,
+ @AdditionalParams NVARCHAR(max)
+)
+AS
+
+ -- check actor rights
+ IF dbo.CanUpdateUserDetails(@ActorID, @UserID) = 0
+ BEGIN
+ RETURN
+ END
+
+ IF @LoginStatusId = 0
+ BEGIN
+ UPDATE Users SET
+ FailedLogins = 0
+ WHERE UserID = @UserID
+ END
+
+ UPDATE Users SET
+ RoleID = @RoleID,
+ StatusID = @StatusID,
+ LoginStatusId = @LoginStatusId,
+ Changed = GetDate(),
+ IsDemo = @IsDemo,
+ IsPeer = @IsPeer,
+ Comments = @Comments,
+ FirstName = @FirstName,
+ LastName = @LastName,
+ Email = @Email,
+ SecondaryEmail = @SecondaryEmail,
+ Address = @Address,
+ City = @City,
+ State = @State,
+ Country = @Country,
+ Zip = @Zip,
+ PrimaryPhone = @PrimaryPhone,
+ SecondaryPhone = @SecondaryPhone,
+ Fax = @Fax,
+ InstantMessenger = @InstantMessenger,
+ HtmlMail = @HtmlMail,
+ CompanyName = @CompanyName,
+ EcommerceEnabled = @EcommerceEnabled,
+ [AdditionalParams] = @AdditionalParams
+ WHERE UserID = @UserID
+
+ RETURN
+GO
+
+
+
+
+
+
+
+
+IF NOT EXISTS (SELECT * FROM sys.objects WHERE type_desc = N'SQL_STORED_PROCEDURE' AND name = N'UpdateUserFailedLoginAttempt')
+BEGIN
+EXEC sp_executesql N' CREATE PROCEDURE [dbo].[UpdateUserFailedLoginAttempt]
+(
+ @UserID int,
+ @LockOut int,
+ @Reset int
+)
+AS
+
+IF (@Reset = 1)
+BEGIN
+ UPDATE Users SET FailedLogins = 0 WHERE UserID = @UserID
+END
+ELSE
+BEGIN
+ IF (@LockOut <= (SELECT FailedLogins FROM USERS WHERE UserID = @UserID))
+ BEGIN
+ UPDATE Users SET LoginStatusId = 2 WHERE UserID = @UserID
+ END
+ ELSE
+ BEGIN
+ IF ((SELECT FailedLogins FROM Users WHERE UserID = @UserID) IS NULL)
+ BEGIN
+ UPDATE Users SET FailedLogins = 1 WHERE UserID = @UserID
+ END
+ ELSE
+ UPDATE Users SET FailedLogins = FailedLogins + 1 WHERE UserID = @UserID
+ END
+END'
+END
+GO
diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Common/BusinessErrorCodes.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Common/BusinessErrorCodes.cs
index 59af6fe0..0b32925f 100644
--- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Common/BusinessErrorCodes.cs
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Common/BusinessErrorCodes.cs
@@ -64,6 +64,9 @@ namespace WebsitePanel.EnterpriseServer
public const int ERROR_INVALID_USER_NAME = -111;
public const int ERROR_USER_ACCOUNT_NOT_ENOUGH_PERMISSIONS = -112;
public const int ERROR_USER_ACCOUNT_ROLE_NOT_ALLOWED = -113;
+
+ public const int ERROR_USER_ACCOUNT_DISABLED = -114;
+ public const int ERROR_USER_ACCOUNT_LOCKEDOUT = -115;
#endregion
#region Packages
diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Users/UserInfo.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Users/UserInfo.cs
index 897f4ebc..a960ad5c 100644
--- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Users/UserInfo.cs
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Users/UserInfo.cs
@@ -33,225 +33,249 @@ using System.Xml.Linq;
namespace WebsitePanel.EnterpriseServer
{
- ///
- /// User account.
- ///
- [Serializable]
- public class UserInfo
- {
- private int userId;
- private int ownerId;
- private int roleId;
- private int statusId;
- private DateTime created;
- private DateTime changed;
- private bool isPeer;
- private bool isDemo;
- private string comments;
- private string username;
- private string password;
- private string firstName;
- private string lastName;
- private string email;
- private string secondaryEmail;
- private string address;
- private string city;
- private string country;
- private string state;
- private string zip;
- private string primaryPhone;
- private string secondaryPhone;
- private string fax;
- private string instantMessenger;
+ ///
+ /// User account.
+ ///
+ [Serializable]
+ public class UserInfo
+ {
+ private int userId;
+ private int ownerId;
+ private int roleId;
+ private int statusId;
+ private int loginStatusId;
+ private int failedLogins;
+ private DateTime created;
+ private DateTime changed;
+ private bool isPeer;
+ private bool isDemo;
+ private string comments;
+ private string username;
+ private string password;
+ private string firstName;
+ private string lastName;
+ private string email;
+ private string secondaryEmail;
+ private string address;
+ private string city;
+ private string country;
+ private string state;
+ private string zip;
+ private string primaryPhone;
+ private string secondaryPhone;
+ private string fax;
+ private string instantMessenger;
private bool htmlMail;
- private string companyName;
- private bool ecommerceEnabled;
+ private string companyName;
+ private bool ecommerceEnabled;
- ///
- /// Creates a new instance of UserInfo class.
- ///
- public UserInfo()
- {
- }
+ ///
+ /// Creates a new instance of UserInfo class.
+ ///
+ public UserInfo()
+ {
+ }
- ///
- /// User role ID:
- /// Administrator = 1,
- /// Reseller = 2,
- /// User = 3
- ///
- public int RoleId
- {
- get { return roleId; }
- set { roleId = value; }
- }
+ ///
+ /// User role ID:
+ /// Administrator = 1,
+ /// Reseller = 2,
+ /// User = 3
+ ///
+ public int RoleId
+ {
+ get { return roleId; }
+ set { roleId = value; }
+ }
- ///
- /// User role.
- ///
- public UserRole Role
- {
- get { return (UserRole)roleId; }
- set { roleId = (int)value; }
- }
- ///
- /// User account status:
- /// Active = 1,
- /// Suspended = 2,
- /// Cancelled = 3,
- /// Pending = 4
- ///
- public int StatusId
- {
- get { return statusId; }
- set { statusId = value; }
- }
+ ///
+ /// User role.
+ ///
+ public UserRole Role
+ {
+ get { return (UserRole)roleId; }
+ set { roleId = (int)value; }
+ }
- ///
- /// User account status.
- ///
- public UserStatus Status
- {
- get { return (UserStatus)statusId; }
- set { statusId = (int)value; }
- }
+ ///
+ /// User account status:
+ /// Active = 1,
+ /// Suspended = 2,
+ /// Cancelled = 3,
+ /// Pending = 4
+ ///
+ public int StatusId
+ {
+ get { return statusId; }
+ set { statusId = value; }
+ }
- ///
- /// User account unique identifier.
- ///
- public int UserId
- {
- get { return userId; }
- set { userId = value; }
- }
+ ///
+ /// User account status.
+ ///
+ public UserStatus Status
+ {
+ get { return (UserStatus)statusId; }
+ set { statusId = (int)value; }
+ }
- public int OwnerId
- {
- get { return ownerId; }
- set { ownerId = value; }
- }
- public bool IsPeer
- {
- get { return isPeer; }
- set { isPeer = value; }
- }
+ public int LoginStatusId
+ {
+ get { return loginStatusId; }
+ set { loginStatusId = value; }
+ }
- public DateTime Created
- {
- get { return created; }
- set { created = value; }
- }
+ public UserLoginStatus LoginStatus
+ {
+ get { return (UserLoginStatus)loginStatusId; }
+ set { loginStatusId = (int)value; }
+ }
- public DateTime Changed
- {
- get { return changed; }
- set { changed = value; }
- }
+ public int FailedLogins
+ {
+ get { return failedLogins; }
+ set { failedLogins = value; }
+ }
- public bool IsDemo
- {
- get { return isDemo; }
- set { isDemo = value; }
- }
- public string Comments
- {
- get { return comments; }
- set { comments = value; }
- }
- public string LastName
- {
- get { return this.lastName; }
- set { this.lastName = value; }
- }
+ ///
+ /// User account unique identifier.
+ ///
+ public int UserId
+ {
+ get { return userId; }
+ set { userId = value; }
+ }
- public string Username
- {
- get { return this.username; }
- set { this.username = value; }
- }
+ public int OwnerId
+ {
+ get { return ownerId; }
+ set { ownerId = value; }
+ }
- public string Password
- {
- get { return this.password; }
- set { this.password = value; }
- }
+ public bool IsPeer
+ {
+ get { return isPeer; }
+ set { isPeer = value; }
+ }
- public string FirstName
- {
- get { return this.firstName; }
- set { this.firstName = value; }
- }
+ public DateTime Created
+ {
+ get { return created; }
+ set { created = value; }
+ }
- public string Email
- {
- get { return this.email; }
- set { this.email = value; }
- }
+ public DateTime Changed
+ {
+ get { return changed; }
+ set { changed = value; }
+ }
- public string PrimaryPhone
- {
- get { return this.primaryPhone; }
- set { this.primaryPhone = value; }
- }
+ public bool IsDemo
+ {
+ get { return isDemo; }
+ set { isDemo = value; }
+ }
- public string Zip
- {
- get { return this.zip; }
- set { this.zip = value; }
- }
+ public string Comments
+ {
+ get { return comments; }
+ set { comments = value; }
+ }
- public string InstantMessenger
- {
- get { return this.instantMessenger; }
- set { this.instantMessenger = value; }
- }
+ public string LastName
+ {
+ get { return this.lastName; }
+ set { this.lastName = value; }
+ }
- public string Fax
- {
- get { return this.fax; }
- set { this.fax = value; }
- }
+ public string Username
+ {
+ get { return this.username; }
+ set { this.username = value; }
+ }
- public string SecondaryPhone
- {
- get { return this.secondaryPhone; }
- set { this.secondaryPhone = value; }
- }
+ public string Password
+ {
+ get { return this.password; }
+ set { this.password = value; }
+ }
- public string SecondaryEmail
- {
- get { return this.secondaryEmail; }
- set { this.secondaryEmail = value; }
- }
+ public string FirstName
+ {
+ get { return this.firstName; }
+ set { this.firstName = value; }
+ }
- public string Country
- {
- get { return this.country; }
- set { this.country = value; }
- }
+ public string Email
+ {
+ get { return this.email; }
+ set { this.email = value; }
+ }
- public string Address
- {
- get { return this.address; }
- set { this.address = value; }
- }
+ public string PrimaryPhone
+ {
+ get { return this.primaryPhone; }
+ set { this.primaryPhone = value; }
+ }
- public string City
- {
- get { return this.city; }
- set { this.city = value; }
- }
+ public string Zip
+ {
+ get { return this.zip; }
+ set { this.zip = value; }
+ }
- public string State
- {
- get { return this.state; }
- set { this.state = value; }
- }
+ public string InstantMessenger
+ {
+ get { return this.instantMessenger; }
+ set { this.instantMessenger = value; }
+ }
+
+ public string Fax
+ {
+ get { return this.fax; }
+ set { this.fax = value; }
+ }
+
+ public string SecondaryPhone
+ {
+ get { return this.secondaryPhone; }
+ set { this.secondaryPhone = value; }
+ }
+
+ public string SecondaryEmail
+ {
+ get { return this.secondaryEmail; }
+ set { this.secondaryEmail = value; }
+ }
+
+ public string Country
+ {
+ get { return this.country; }
+ set { this.country = value; }
+ }
+
+ public string Address
+ {
+ get { return this.address; }
+ set { this.address = value; }
+ }
+
+ public string City
+ {
+ get { return this.city; }
+ set { this.city = value; }
+ }
+
+ public string State
+ {
+ get { return this.state; }
+ set { this.state = value; }
+ }
public bool HtmlMail
{
@@ -259,17 +283,17 @@ namespace WebsitePanel.EnterpriseServer
set { this.htmlMail = value; }
}
- public string CompanyName
- {
- get { return this.companyName; }
- set { this.companyName = value; }
- }
+ public string CompanyName
+ {
+ get { return this.companyName; }
+ set { this.companyName = value; }
+ }
- public bool EcommerceEnabled
- {
- get { return this.ecommerceEnabled; }
- set { this.ecommerceEnabled = value; }
- }
+ public bool EcommerceEnabled
+ {
+ get { return this.ecommerceEnabled; }
+ set { this.ecommerceEnabled = value; }
+ }
public string AdditionalParams { get; set; }
@@ -289,10 +313,10 @@ namespace WebsitePanel.EnterpriseServer
XElement vLansElement = doc.Root.Element("VLans");
if (vLansElement != null)
{
- foreach(var item in vLansElement.Elements("VLan"))
+ foreach (var item in vLansElement.Elements("VLan"))
result.Add(new UserVlan
{
- VLanID = item.Attribute("VLanID") != null ? ushort.Parse(item.Attribute("VLanID").Value) : (ushort) 0,
+ VLanID = item.Attribute("VLanID") != null ? ushort.Parse(item.Attribute("VLanID").Value) : (ushort)0,
Comment = item.Attribute("Comment") != null ? item.Attribute("Comment").Value : null
});
}
@@ -304,7 +328,7 @@ namespace WebsitePanel.EnterpriseServer
return result;
}
}
- }
+ }
///
/// User's VLans
diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Users/UserLoginStatus.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Users/UserLoginStatus.cs
new file mode 100644
index 00000000..ee564350
--- /dev/null
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Users/UserLoginStatus.cs
@@ -0,0 +1,42 @@
+// Copyright (c) 2012, 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;
+
+namespace WebsitePanel.EnterpriseServer
+{
+ ///
+ /// Summary description for AccountLoginStatus.
+ ///
+ public enum UserLoginStatus
+ {
+ Enabled = 0,
+ Disabled = 1,
+ LockedOut = 2
+ }
+}
diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Users/UserSettings.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Users/UserSettings.cs
index 3c0c122b..b69dfc04 100644
--- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Users/UserSettings.cs
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Users/UserSettings.cs
@@ -41,6 +41,7 @@ namespace WebsitePanel.EnterpriseServer
public const string PACKAGE_SUMMARY_LETTER = "PackageSummaryLetter";
public const string PASSWORD_REMINDER_LETTER = "PasswordReminderLetter";
public const string EXCHANGE_MAILBOX_SETUP_LETTER = "ExchangeMailboxSetupLetter";
+ public const string EXCHANGE_HOSTED_EDITION_ORGANIZATION_SUMMARY = "ExchangeHostedEditionOrganizationSummary";
public const string HOSTED_SOLUTION_REPORT = "HostedSoluitonReportSummaryLetter";
public const string ORGANIZATION_USER_SUMMARY_LETTER = "OrganizationUserSummaryLetter";
public const string VPS_SUMMARY_LETTER = "VpsSummaryLetter";
@@ -51,7 +52,8 @@ namespace WebsitePanel.EnterpriseServer
public const string MYSQL_POLICY = "MySqlPolicy";
public const string SHAREPOINT_POLICY = "SharePointPolicy";
public const string OS_POLICY = "OsPolicy";
- public const string EXCHANGE_POLICY = "ExchangePolicy";
+ public const string EXCHANGE_POLICY = "ExchangePolicy";
+ public const string EXCHANGE_HOSTED_EDITION_POLICY = "ExchangeHostedEditionPolicy";
public const string WEBSITEPANEL_POLICY = "WebsitePanelPolicy";
public const string VPS_POLICY = "VpsPolicy";
public const string DISPLAY_PREFS = "DisplayPreferences";
diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Users/UserStatus.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Users/UserStatus.cs
index 6384e90b..d7a2fda4 100644
--- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Users/UserStatus.cs
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Users/UserStatus.cs
@@ -30,14 +30,14 @@ using System;
namespace WebsitePanel.EnterpriseServer
{
- ///
- /// Summary description for AccountStatus.
- ///
- public enum UserStatus
- {
- Active = 1,
- Suspended = 2,
- Cancelled = 3,
- Pending = 4
- }
+ ///
+ /// Summary description for AccountStatus.
+ ///
+ public enum UserStatus
+ {
+ Active = 1,
+ Suspended = 2,
+ Cancelled = 3,
+ Pending = 4
+ }
}
diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/WebsitePanel.EnterpriseServer.Base.csproj b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/WebsitePanel.EnterpriseServer.Base.csproj
index 8c1018da..9350215a 100644
--- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/WebsitePanel.EnterpriseServer.Base.csproj
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/WebsitePanel.EnterpriseServer.Base.csproj
@@ -156,6 +156,7 @@
+
diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/Code/Data/DataProvider.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/Code/Data/DataProvider.cs
index ab9c9fd6..6d85886e 100644
--- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/Code/Data/DataProvider.cs
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/Code/Data/DataProvider.cs
@@ -190,7 +190,7 @@ namespace WebsitePanel.EnterpriseServer
new SqlParameter("@Username", username));
}
- public static int AddUser(int actorId, int ownerId, int roleId, int statusId, bool isDemo,
+ public static int AddUser(int actorId, int ownerId, int roleId, int statusId, int loginStatusId, bool isDemo,
bool isPeer, string comments, string username, string password,
string firstName, string lastName, string email, string secondaryEmail,
string address, string city, string country, string state, string zip,
@@ -208,6 +208,7 @@ namespace WebsitePanel.EnterpriseServer
new SqlParameter("@OwnerID", ownerId),
new SqlParameter("@RoleID", roleId),
new SqlParameter("@StatusId", statusId),
+ new SqlParameter("@LoginStatusId", loginStatusId),
new SqlParameter("@IsDemo", isDemo),
new SqlParameter("@IsPeer", isPeer),
new SqlParameter("@Comments", comments),
@@ -227,13 +228,13 @@ namespace WebsitePanel.EnterpriseServer
new SqlParameter("@fax", fax),
new SqlParameter("@instantMessenger", instantMessenger),
new SqlParameter("@htmlMail", htmlMail),
- new SqlParameter("@CompanyName", companyName),
- new SqlParameter("@EcommerceEnabled", ecommerceEnabled));
+ new SqlParameter("@CompanyName", companyName),
+ new SqlParameter("@EcommerceEnabled", ecommerceEnabled));
return Convert.ToInt32(prmUserId.Value);
}
- public static void UpdateUser(int actorId, int userId, int roleId, int statusId, bool isDemo,
+ public static void UpdateUser(int actorId, int userId, int roleId, int statusId, int loginStatusId, bool isDemo,
bool isPeer, string comments, string firstName, string lastName, string email, string secondaryEmail,
string address, string city, string country, string state, string zip,
string primaryPhone, string secondaryPhone, string fax, string instantMessenger, bool htmlMail,
@@ -245,6 +246,7 @@ namespace WebsitePanel.EnterpriseServer
new SqlParameter("@ActorId", actorId),
new SqlParameter("@RoleID", roleId),
new SqlParameter("@StatusId", statusId),
+ new SqlParameter("@LoginStatusId", loginStatusId),
new SqlParameter("@UserID", userId),
new SqlParameter("@IsDemo", isDemo),
new SqlParameter("@IsPeer", isPeer),
@@ -263,11 +265,20 @@ namespace WebsitePanel.EnterpriseServer
new SqlParameter("@fax", fax),
new SqlParameter("@instantMessenger", instantMessenger),
new SqlParameter("@htmlMail", htmlMail),
- new SqlParameter("@CompanyName", companyName),
- new SqlParameter("@EcommerceEnabled", ecommerceEnabled),
+ new SqlParameter("@CompanyName", companyName),
+ new SqlParameter("@EcommerceEnabled", ecommerceEnabled),
new SqlParameter("@AdditionalParams", additionalParams));
}
+ public static void UpdateUserFailedLoginAttempt(int userId, int lockOut, bool reset)
+ {
+ SqlHelper.ExecuteNonQuery(ConnectionString, CommandType.StoredProcedure,
+ ObjectQualifier + "UpdateUserFailedLoginAttempt",
+ new SqlParameter("@UserID", userId),
+ new SqlParameter("@LockOut", lockOut),
+ new SqlParameter("@Reset", reset));
+ }
+
public static void DeleteUser(int actorId, int userId)
{
SqlHelper.ExecuteNonQuery(ConnectionString, CommandType.StoredProcedure,
diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/Code/Users/UserController.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/Code/Users/UserController.cs
index ecbb824a..8ca4b341 100644
--- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/Code/Users/UserController.cs
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/Code/Users/UserController.cs
@@ -49,56 +49,92 @@ namespace WebsitePanel.EnterpriseServer
return (user != null);
}
- public static int AuthenticateUser(string username, string password, string ip)
- {
- // start task
- TaskManager.StartTask("USER", "AUTHENTICATE", username);
- TaskManager.WriteParameter("IP", ip);
+ public static int AuthenticateUser(string username, string password, string ip)
+ {
+ // start task
+ TaskManager.StartTask("USER", "AUTHENTICATE", username);
+ TaskManager.WriteParameter("IP", ip);
- try
- {
- // try to get user from database
- UserInfo user = GetUserInternally(username);
+ try
+ {
+ // try to get user from database
+ UserInfo user = GetUserInternally(username);
- // check if the user exists
- if (user == null)
- {
- TaskManager.WriteWarning("Wrong username");
- return BusinessErrorCodes.ERROR_USER_WRONG_USERNAME;
- }
+ // check if the user exists
+ if (user == null)
+ {
+ TaskManager.WriteWarning("Wrong username");
+ return BusinessErrorCodes.ERROR_USER_WRONG_USERNAME;
+ }
- // compare user passwords
- if (user.Password != password)
- {
- TaskManager.WriteWarning("Wrong password");
- return BusinessErrorCodes.ERROR_USER_WRONG_PASSWORD;
- }
+ // check if the user is disabled
+ if (user.LoginStatus == UserLoginStatus.Disabled)
+ {
+ TaskManager.WriteWarning("User disabled");
+ return BusinessErrorCodes.ERROR_USER_ACCOUNT_DISABLED;
+ }
- // check status
- if (user.Status == UserStatus.Cancelled)
- {
- TaskManager.WriteWarning("Account cancelled");
- return BusinessErrorCodes.ERROR_USER_ACCOUNT_CANCELLED;
- }
+ // check if the user is locked out
+ if (user.LoginStatus == UserLoginStatus.LockedOut)
+ {
+ TaskManager.WriteWarning("User locked out");
+ return BusinessErrorCodes.ERROR_USER_ACCOUNT_LOCKEDOUT;
+ }
- if (user.Status == UserStatus.Pending)
- {
- TaskManager.WriteWarning("Account pending");
- return BusinessErrorCodes.ERROR_USER_ACCOUNT_PENDING;
- }
+ //Get the password policy
+ UserSettings userSettings = UserController.GetUserSettings(user.UserId, UserSettings.WEBSITEPANEL_POLICY);
+ int lockOut = -1;
- return 0;
+ if (!string.IsNullOrEmpty(userSettings["PasswordPolicy"]))
+ {
+ string passwordPolicy = userSettings["PasswordPolicy"];
+ try
+ {
+ // parse settings
+ string[] parts = passwordPolicy.Split(';');
+ lockOut = Convert.ToInt32(parts[7]);
+ }
+ catch { /* skip */ }
+ }
- }
- catch (Exception ex)
- {
- throw TaskManager.WriteError(ex);
- }
- finally
- {
- TaskManager.CompleteTask();
- }
- }
+
+ // compare user passwords
+ if (user.Password != password)
+ {
+ if (lockOut >= 0)
+ DataProvider.UpdateUserFailedLoginAttempt(user.UserId, lockOut, false);
+
+ TaskManager.WriteWarning("Wrong password");
+ return BusinessErrorCodes.ERROR_USER_WRONG_PASSWORD;
+ }
+ else
+ DataProvider.UpdateUserFailedLoginAttempt(user.UserId, lockOut, true);
+
+ // check status
+ if (user.Status == UserStatus.Cancelled)
+ {
+ TaskManager.WriteWarning("Account cancelled");
+ return BusinessErrorCodes.ERROR_USER_ACCOUNT_CANCELLED;
+ }
+
+ if (user.Status == UserStatus.Pending)
+ {
+ TaskManager.WriteWarning("Account pending");
+ return BusinessErrorCodes.ERROR_USER_ACCOUNT_PENDING;
+ }
+
+ return 0;
+
+ }
+ catch (Exception ex)
+ {
+ throw TaskManager.WriteError(ex);
+ }
+ finally
+ {
+ TaskManager.CompleteTask();
+ }
+ }
public static UserInfo GetUserByUsernamePassword(string username, string password, string ip)
{
@@ -382,6 +418,7 @@ namespace WebsitePanel.EnterpriseServer
user.OwnerId,
user.RoleId,
user.StatusId,
+ user.LoginStatusId,
user.IsDemo,
user.IsPeer,
user.Comments,
@@ -525,6 +562,7 @@ namespace WebsitePanel.EnterpriseServer
user.UserId,
user.RoleId,
user.StatusId,
+ user.LoginStatusId,
user.IsDemo,
user.IsPeer,
user.Comments,
diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/App_Data/ModulesData.config b/WebsitePanel/Sources/WebsitePanel.WebPortal/App_Data/ModulesData.config
index 65182013..efd04273 100644
--- a/WebsitePanel/Sources/WebsitePanel.WebPortal/App_Data/ModulesData.config
+++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/App_Data/ModulesData.config
@@ -2,15 +2,15 @@