From 1e0a0710fdbe7d771aa6b789d509c2193ccb86ef Mon Sep 17 00:00:00 2001 From: Alexander Trofimov Date: Sun, 17 May 2015 23:47:38 +0300 Subject: [PATCH] One time password on forgot password --- WebsitePanel/Database/install_db.sql | 8 +- WebsitePanel/Database/update_db.sql | 134 +++++++++++++++++- .../Common/BusinessErrorCodes.cs | 3 + .../Common/BusinessSuccessCodes.cs | 43 ++++++ .../Users/OneTimePasswordStates.cs | 14 ++ .../Users/UserInfo.cs | 67 ++------- .../WebsitePanel.EnterpriseServer.Base.csproj | 2 + .../Data/DataProvider.cs | 9 ++ .../Users/Helpers/OneTimePasswordHelper.cs | 41 ++++++ .../Users/UserController.cs | 95 +++++++------ .../WebsitePanel.EnterpriseServer.Code.csproj | 1 + .../App_Data/WebsitePanel_Modules.config | 3 +- .../WebsitePanel_SharedResources.ascx.resx | 3 + .../Code/PortalUtils.cs | 2 +- .../DesktopModules/WebsitePanel/Login.ascx.cs | 5 + .../UserAccountChangePassword.ascx.cs | 5 + 16 files changed, 326 insertions(+), 109 deletions(-) create mode 100644 WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Common/BusinessSuccessCodes.cs create mode 100644 WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Users/OneTimePasswordStates.cs create mode 100644 WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Users/Helpers/OneTimePasswordHelper.cs diff --git a/WebsitePanel/Database/install_db.sql b/WebsitePanel/Database/install_db.sql index a9774f04..a97d294f 100644 --- a/WebsitePanel/Database/install_db.sql +++ b/WebsitePanel/Database/install_db.sql @@ -44365,7 +44365,7 @@ Hello #user.FirstName#,

-Please, find below details of your control panel account. +Please, find below details of your control panel account. The one time password was generated for you. You should change the password after login.

Control Panel URL

@@ -44374,7 +44374,7 @@ Please, find below details of your control panel account. Control Panel URL Username - Password + One Time Password @@ -44412,11 +44412,11 @@ INSERT [dbo].[UserSettings] ([UserID], [SettingsName], [PropertyName], [Property Hello #user.FirstName#, -Please, find below details of your control panel account. +Please, find below details of your control panel account. The one time password was generated for you. You should change the password after login. Control Panel URL: http://panel.AcmeHosting.com Username: #user.Username# -Password: #user.Password# +One Time Password: #user.Password# If you have any questions regarding your hosting account, feel free to contact our support department at any time. diff --git a/WebsitePanel/Database/update_db.sql b/WebsitePanel/Database/update_db.sql index 034796f1..8ae8e21f 100644 --- a/WebsitePanel/Database/update_db.sql +++ b/WebsitePanel/Database/update_db.sql @@ -12444,4 +12444,136 @@ BEGIN DECLARE @item_type_id AS INT SELECT @item_type_id = ItemTypeId FROM ServiceItemTypes WHERE DisplayName = 'SharePointEnterpriseSiteCollection' UPDATE [dbo].[Quotas] SET ItemTypeID = @item_type_id WHERE QuotaId = 550 -END \ No newline at end of file +END +GO + +-- OneTimePassword +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='OneTimePasswordState') +BEGIN +ALTER TABLE [dbo].[Users] ADD + [OneTimePasswordState] int NULL +END +GO + +IF EXISTS (SELECT * FROM SYS.OBJECTS WHERE type = 'P' AND name = 'SetUserOneTimePassword') +DROP PROCEDURE SetUserOneTimePassword +GO +CREATE PROCEDURE [dbo].[SetUserOneTimePassword] +( + @UserID int, + @Password nvarchar(200), + @OneTimePasswordState int +) +AS +UPDATE Users +SET Password = @Password, OneTimePasswordState = @OneTimePasswordState +WHERE UserID = @UserID +RETURN +GO + +ALTER PROCEDURE [dbo].[GetUserByUsernameInternally] +( + @Username nvarchar(50) +) +AS + SELECT + U.UserID, + U.RoleID, + U.StatusID, + U.SubscriberNumber, + 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], + U.OneTimePasswordState + FROM Users AS U + WHERE U.Username = @Username + + RETURN +GO + +ALTER PROCEDURE [dbo].[GetUserByIdInternally] +( + @UserID int +) +AS + SELECT + U.UserID, + U.RoleID, + U.StatusID, + U.SubscriberNumber, + 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], + U.OneTimePasswordState + FROM Users AS U + WHERE U.UserID = @UserID + + RETURN +GO + +ALTER PROCEDURE [dbo].[ChangeUserPassword] +( + @ActorID int, + @UserID int, + @Password nvarchar(200) +) +AS + +-- check actor rights +IF dbo.CanUpdateUserDetails(@ActorID, @UserID) = 0 +RETURN + +UPDATE Users +SET Password = @Password, OneTimePasswordState = 0 +WHERE UserID = @UserID + +RETURN +GO \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Common/BusinessErrorCodes.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Common/BusinessErrorCodes.cs index dc4f432d..6b74dda9 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Common/BusinessErrorCodes.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Common/BusinessErrorCodes.cs @@ -67,6 +67,9 @@ namespace WebsitePanel.EnterpriseServer public const int ERROR_USER_ACCOUNT_DISABLED = -114; public const int ERROR_USER_ACCOUNT_LOCKEDOUT = -115; + + public const int ERROR_USER_EXPIRED_ONETIMEPASSWORD = -116; + #endregion #region Packages diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Common/BusinessSuccessCodes.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Common/BusinessSuccessCodes.cs new file mode 100644 index 00000000..b2650f6e --- /dev/null +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Common/BusinessSuccessCodes.cs @@ -0,0 +1,43 @@ +// Copyright (c) 2015, 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.Collections.Generic; +using System.Text; + +namespace WebsitePanel.EnterpriseServer +{ + public class BusinessSuccessCodes + { + #region Users + + public const int SUCCESS_USER_ONETIMEPASSWORD = 100; + + #endregion + } +} diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Users/OneTimePasswordStates.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Users/OneTimePasswordStates.cs new file mode 100644 index 00000000..bf80149f --- /dev/null +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Users/OneTimePasswordStates.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace WebsitePanel.EnterpriseServer +{ + public enum OneTimePasswordStates + { + None = 0, + Active = 1, + Expired = 2, + } +} diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Users/UserInfo.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Users/UserInfo.cs index 1850c5bf..c8bd79b8 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Users/UserInfo.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Users/UserInfo.cs @@ -385,68 +385,19 @@ namespace WebsitePanel.EnterpriseServer public class UserInfoInternal : UserInfo { private string password; + private string oneTimePassword; + private OneTimePasswordStates oneTimePasswordState; public string Password { get { return this.password; } set { this.password = value; } } + + public OneTimePasswordStates OneTimePasswordState + { + get { return oneTimePasswordState; } + set { oneTimePasswordState = value; } + } }; -} - - - - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esAuthentication.asmx.cs(51): public int AuthenticateUser(string username, string password, string ip) - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esAuthentication.asmx.cs(57): public UserInfo GetUserByUsernamePassword(string username, string password, string ip) - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esAuthentication.asmx.cs(63): public int ChangeUserPasswordByUsername(string username, string oldPassword, string newPassword, string ip) - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esAuthentication.asmx.cs(69): public int SendPasswordReminder(string username, string ip) - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esAuthentication.asmx.cs(81): public int SetupControlPanelAccounts(string passwordA, string passwordB, string ip) - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esBlackBerry.asmx.cs(92): public ResultObject SetActivationPasswordWithExpirationTime(int itemId, int accountId, string password, int time) - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esExchangeServer.asmx.cs(221): public bool CheckAccountCredentials(int itemId, string email, string password) - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esExchangeServer.asmx.cs(231): public int CreateMailbox(int itemId, int accountId, ExchangeAccountType accountType, string accountName, string displayName, - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esExchangeServer.asmx.cs(231): string name, string domain, string password, bool sendSetupInstructions, string setupInstructionMailAddress, int mailboxPlanId, int archivedPlanId, string subscriberNumber, bool EnableArchiving) - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esOrganizations.asmx.cs(195): public ResultObject SendResetUserPasswordLinkSms(int itemId, int accountId, string reason, string phoneTo = null) - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esOrganizations.asmx.cs(197): return OrganizationController.SendResetUserPasswordLinkSms(itemId, accountId, reason, phoneTo); - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esOrganizations.asmx.cs(202): public ResultObject SendResetUserPasswordPincodeSms(Guid token, string phoneTo = null) - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esOrganizations.asmx.cs(204): return OrganizationController.SendResetUserPasswordPincodeSms(token, phoneTo); - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esOrganizations.asmx.cs(259): public int CreateUser(int itemId, string displayName, string name, string domain, string password, string subscriberNumber, bool sendNotification, string to) - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esOrganizations.asmx.cs(262): return OrganizationController.CreateUser(itemId, displayName, name, domain, password, subscriberNumber, true, sendNotification, to, out accountName); - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esOrganizations.asmx.cs(266): public int ImportUser(int itemId, string accountName, string displayName, string name, string domain, string password, string subscriberNumber) - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esOrganizations.asmx.cs(268): return OrganizationController.ImportUser(itemId, accountName, displayName, name, domain, password, subscriberNumber); - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esOrganizations.asmx.cs(293): string password, bool hideAddressBook, bool disabled, bool locked, string firstName, string initials, - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esOrganizations.asmx.cs(298): bool userMustChangePassword) - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esOrganizations.asmx.cs(301): password, hideAddressBook, disabled, locked, firstName, initials, - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esOrganizations.asmx.cs(305): webPage, notes, externalEmail, subscriberNumber, levelId, isVIP, userMustChangePassword); - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esOrganizations.asmx.cs(318): public int SetUserPassword(int itemId, int accountId, string password) - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esOrganizations.asmx.cs(320): return OrganizationController.SetUserPassword(itemId, accountId, password); - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esOrganizations.asmx.cs(353): public PasswordPolicyResult GetPasswordPolicy(int itemId) - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esOrganizations.asmx.cs(355): return OrganizationController.GetPasswordPolicy(itemId); - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esOrganizations.asmx.cs(359): public void SendResetUserPasswordEmail(int itemId, int accountId, string reason, string mailTo, bool finalStep) - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esOrganizations.asmx.cs(361): OrganizationController.SendResetUserPasswordEmail(itemId, accountId, reason, mailTo, finalStep); - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esPackages.asmx.cs(449): public int CreateUserWizard(int parentPackageId, string username, string password, - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esPackages.asmx.cs(456): return UserCreationWizard.CreateUserAccount(parentPackageId, username, password, - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esServers.asmx.cs(108): public int CheckServerAvailable(string serverUrl, string password) - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esServers.asmx.cs(110): return ServerController.CheckServerAvailable(serverUrl, password); - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esServers.asmx.cs(126): public int UpdateServerConnectionPassword(int serverId, string password) - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esServers.asmx.cs(128): return ServerController.UpdateServerConnectionPassword(serverId, password); - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esServers.asmx.cs(132): public int UpdateServerADPassword(int serverId, string adPassword) - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esServers.asmx.cs(134): return ServerController.UpdateServerADPassword(serverId, adPassword); - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esUsers.asmx.cs(152): string password, - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esUsers.asmx.cs(178): user.Password = password; - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esUsers.asmx.cs(272): public int ChangeUserPassword(int userId, string password) - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esUsers.asmx.cs(274): return UserController.ChangeUserPassword(userId, password); - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esWebServers.asmx.cs(127): return WebServerController.InstallFrontPage(siteItemId, username, password); - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esWebServers.asmx.cs(137): public int ChangeFrontPagePassword(int siteItemId, string password) - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esWebServers.asmx.cs(139): return WebServerController.ChangeFrontPagePassword(siteItemId, password); - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esWebServers.asmx.cs(337): public ResultObject GrantWebDeployPublishingAccess(int siteItemId, string accountName, string accountPassword) - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esWebServers.asmx.cs(339): return WebServerController.GrantWebDeployPublishingAccess(siteItemId, accountName, accountPassword); - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esWebServers.asmx.cs(361): public ResultObject ChangeWebDeployPublishingPassword(int siteItemId, string newAccountPassword) - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esWebServers.asmx.cs(363): return WebServerController.ChangeWebDeployPublishingPassword(siteItemId, newAccountPassword); - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esWebServers.asmx.cs(536): public ResultObject GrantWebManagementAccess(int siteItemId, string accountName, string accountPassword) - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esWebServers.asmx.cs(538): return WebServerController.GrantWebManagementAccess(siteItemId, accountName, accountPassword); - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esWebServers.asmx.cs(548): public ResultObject ChangeWebManagementAccessPassword(int siteItemId, string accountPassword) - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esWebServers.asmx.cs(550): return WebServerController.ChangeWebManagementAccessPassword(siteItemId, accountPassword); - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esWebServers.asmx.cs(567): public ResultObject InstallPfx(byte[] certificate, int siteItemId, string password) - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esWebServers.asmx.cs(569): return WebServerController.InstallPfx(certificate, siteItemId, password); - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esWebServers.asmx.cs(597): public byte[] ExportCertificate(int siteId, string serialNumber, string password) - //C:\Work\WSPExpert\WebsitePanel\Sources\WebsitePanel.EnterpriseServer\esWebServers.asmx.cs(599): return WebServerController.ExportCertificate(siteId, serialNumber, password); \ No newline at end of file +} \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/WebsitePanel.EnterpriseServer.Base.csproj b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/WebsitePanel.EnterpriseServer.Base.csproj index 3a24cbb4..1e101918 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/WebsitePanel.EnterpriseServer.Base.csproj +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/WebsitePanel.EnterpriseServer.Base.csproj @@ -69,6 +69,7 @@ VersionInfo.cs + Code @@ -165,6 +166,7 @@ + diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Data/DataProvider.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Data/DataProvider.cs index 8c42edb9..a5549230 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Data/DataProvider.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Data/DataProvider.cs @@ -382,6 +382,15 @@ namespace WebsitePanel.EnterpriseServer new SqlParameter("@password", password)); } + public static void SetUserOneTimePassword(int userId, string password, int auths) + { + SqlHelper.ExecuteNonQuery(ConnectionString, CommandType.StoredProcedure, + ObjectQualifier + "SetUserOneTimePassword", + new SqlParameter("@UserID", userId), + new SqlParameter("@Password", password), + new SqlParameter("@OneTimePasswordState", auths)); + } + #endregion #region User Settings diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Users/Helpers/OneTimePasswordHelper.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Users/Helpers/OneTimePasswordHelper.cs new file mode 100644 index 00000000..3e515ddb --- /dev/null +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Users/Helpers/OneTimePasswordHelper.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace WebsitePanel.EnterpriseServer +{ + public class OneTimePasswordHelper + { + public static string SetOneTimePassword(int userId) + { + int passwordLength = 12; // default length + + // load password policy + UserSettings userSettings = UserController.GetUserSettings(userId, UserSettings.WEBSITEPANEL_POLICY); + string passwordPolicy = userSettings["PasswordPolicy"]; + + if (!String.IsNullOrEmpty(passwordPolicy)) + { + // get third parameter - max length + try + { + passwordLength = Utils.ParseInt(passwordPolicy.Split(';')[2].Trim(), passwordLength); + } + catch { /* skip */ } + } + + // generate password + var password = Utils.GetRandomString(passwordLength); + + DataProvider.SetUserOneTimePassword(userId, CryptoUtils.Encrypt(password), (int) OneTimePasswordStates.Active); + + return password; + } + + public static void FireSuccessAuth(UserInfoInternal user) + { + DataProvider.SetUserOneTimePassword(user.UserId, CryptoUtils.Encrypt(user.Password), (int) OneTimePasswordStates.Expired); + } + } +} diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Users/UserController.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Users/UserController.cs index fabe98bc..7c5b85f3 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Users/UserController.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Users/UserController.cs @@ -57,6 +57,8 @@ namespace WebsitePanel.EnterpriseServer try { + int result = 0; + // try to get user from database UserInfoInternal user = GetUserInternally(username); @@ -99,16 +101,31 @@ namespace WebsitePanel.EnterpriseServer // compare user passwords - if (CryptoUtils.SHA1(user.Password) != password) + if (CryptoUtils.SHA1(user.Password) == password) + { + switch (user.OneTimePasswordState) + { + case OneTimePasswordStates.Active: + result = BusinessSuccessCodes.SUCCESS_USER_ONETIMEPASSWORD; + OneTimePasswordHelper.FireSuccessAuth(user); + break; + case OneTimePasswordStates.Expired: + if (lockOut >= 0) DataProvider.UpdateUserFailedLoginAttempt(user.UserId, lockOut, false); + TaskManager.WriteWarning("Expired one time password"); + return BusinessErrorCodes.ERROR_USER_EXPIRED_ONETIMEPASSWORD; + break; + } + } + else { if (lockOut >= 0) DataProvider.UpdateUserFailedLoginAttempt(user.UserId, lockOut, false); TaskManager.WriteWarning("Wrong password"); - return BusinessErrorCodes.ERROR_USER_WRONG_PASSWORD; + return BusinessErrorCodes.ERROR_USER_WRONG_PASSWORD; } - else - DataProvider.UpdateUserFailedLoginAttempt(user.UserId, lockOut, true); + + DataProvider.UpdateUserFailedLoginAttempt(user.UserId, lockOut, true); // check status if (user.Status == UserStatus.Cancelled) @@ -123,7 +140,7 @@ namespace WebsitePanel.EnterpriseServer return BusinessErrorCodes.ERROR_USER_ACCOUNT_PENDING; } - return 0; + return result; } catch (Exception ex) @@ -155,7 +172,7 @@ namespace WebsitePanel.EnterpriseServer } // compare user passwords - if (CryptoUtils.SHA1(user.Password) == password) + if (CryptoUtils.SHA1(user.Password) == password) return new UserInfo(user); return null; @@ -210,7 +227,7 @@ namespace WebsitePanel.EnterpriseServer try { // try to get user from database - UserInfo user = GetUserInternally(username); + UserInfoInternal user = GetUserInternally(username); if (user == null) { TaskManager.WriteWarning("Account not found"); @@ -232,18 +249,20 @@ namespace WebsitePanel.EnterpriseServer if (body == null || body == "") return BusinessErrorCodes.ERROR_SETTINGS_PASSWORD_LETTER_EMPTY_BODY; + + // One Time Password feature + user.Password = OneTimePasswordHelper.SetOneTimePassword(user.UserId); - // set template context items - Hashtable items = new Hashtable(); - items["user"] = user; - items["Email"] = true; + // set template context items + Hashtable items = new Hashtable(); + items["user"] = user; + items["Email"] = true; - // get reseller details + // get reseller details UserInfoInternal reseller = UserController.GetUser(user.OwnerId); if (reseller != null) { - reseller.Password = ""; - items["reseller"] = reseller; + items["reseller"] = new UserInfo(reseller); } subject = PackageController.EvaluateTemplate(subject, items); @@ -264,52 +283,40 @@ namespace WebsitePanel.EnterpriseServer } } + internal static UserInfoInternal GetUserInternally(int userId) { - // try to get user from database - UserInfoInternal user = ObjectUtils.FillObjectFromDataReader( - DataProvider.GetUserByIdInternally(userId)); - - if (user != null) - user.Password = CryptoUtils.Decrypt(user.Password); - return user; + return GetUser(DataProvider.GetUserByIdInternally(userId)); } internal static UserInfoInternal GetUserInternally(string username) { - // try to get user from database - UserInfoInternal user = ObjectUtils.FillObjectFromDataReader( - DataProvider.GetUserByUsernameInternally(username)); - - if (user != null) - { - user.Password = CryptoUtils.Decrypt(user.Password); - } - return user; + return GetUser(DataProvider.GetUserByUsernameInternally(username)); } public static UserInfoInternal GetUser(int userId) { - // try to get user from database - UserInfoInternal user = ObjectUtils.FillObjectFromDataReader( - DataProvider.GetUserById(SecurityContext.User.UserId, userId)); - - if (user != null) - user.Password = CryptoUtils.Decrypt(user.Password); - return user; + return GetUser(DataProvider.GetUserById(SecurityContext.User.UserId, userId)); } public static UserInfoInternal GetUser(string username) { - // try to get user from database - UserInfoInternal user = ObjectUtils.FillObjectFromDataReader( - DataProvider.GetUserByUsername(SecurityContext.User.UserId, username)); - - if (user != null) - user.Password = CryptoUtils.Decrypt(user.Password); - return user; + return GetUser(DataProvider.GetUserByUsername(SecurityContext.User.UserId, username)); } + private static UserInfoInternal GetUser(IDataReader reader) + { + // try to get user from database + UserInfoInternal user = ObjectUtils.FillObjectFromDataReader(reader); + + if (user != null) + { + user.Password = CryptoUtils.Decrypt(user.Password); + } + + return user; + } + public static List GetUserParents(int userId) { // get users from database diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/WebsitePanel.EnterpriseServer.Code.csproj b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/WebsitePanel.EnterpriseServer.Code.csproj index 21b45545..4287066b 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/WebsitePanel.EnterpriseServer.Code.csproj +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/WebsitePanel.EnterpriseServer.Code.csproj @@ -183,6 +183,7 @@ + diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/App_Data/WebsitePanel_Modules.config b/WebsitePanel/Sources/WebsitePanel.WebPortal/App_Data/WebsitePanel_Modules.config index 63c4235e..890072ed 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/App_Data/WebsitePanel_Modules.config +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/App_Data/WebsitePanel_Modules.config @@ -401,7 +401,8 @@ - + + diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/App_GlobalResources/WebsitePanel_SharedResources.ascx.resx b/WebsitePanel/Sources/WebsitePanel.WebPortal/App_GlobalResources/WebsitePanel_SharedResources.ascx.resx index d83c52e3..531432c3 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/App_GlobalResources/WebsitePanel_SharedResources.ascx.resx +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/App_GlobalResources/WebsitePanel_SharedResources.ascx.resx @@ -4581,6 +4581,9 @@ User account is Suspended + + You should change your one time password. + Hostname pattern is not specified. Could not create VPS with blank hostname. diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/Code/PortalUtils.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/Code/PortalUtils.cs index d3c706c0..9031ad43 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/Code/PortalUtils.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/Code/PortalUtils.cs @@ -382,7 +382,7 @@ namespace WebsitePanel.Portal else return BusinessErrorCodes.ERROR_USER_ACCOUNT_ROLE_NOT_ALLOWED; } - return 0; + return authResult; } } catch (Exception ex) diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/Login.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/Login.ascx.cs index 866f8426..2846d625 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/Login.ascx.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/Login.ascx.cs @@ -186,6 +186,11 @@ namespace WebsitePanel.Portal { ShowWarningMessage("WrongLogin"); } + else if (loginStatus == BusinessSuccessCodes.SUCCESS_USER_ONETIMEPASSWORD) + { + // One time password should be changed after login + Response.Redirect(EditUrl("UserID", PanelSecurity.LoggedUserId.ToString(), "change_onetimepassword", "onetimepassword=true"), true); + } else { // redirect by shortcut diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/UserAccountChangePassword.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/UserAccountChangePassword.ascx.cs index 81c68ccf..9b260aee 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/UserAccountChangePassword.ascx.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/UserAccountChangePassword.ascx.cs @@ -80,6 +80,11 @@ namespace WebsitePanel.Portal if (!String.IsNullOrEmpty(changePasswordWarningText)) lblChangePasswordWarning.Text = changePasswordWarningText; } + + if (PanelRequest.GetBool("onetimepassword")) + { + ShowWarningMessage("USER_SHOULD_CHANGE_ONETIMEPASSWORD"); + } } catch (Exception ex) {