From 7bd6628bea30dfd35097a22676d912d96e2efddf Mon Sep 17 00:00:00 2001 From: vfedosevich Date: Fri, 24 Apr 2015 06:19:11 -0700 Subject: [PATCH] password reset link sms added --- WebsitePanel/Database/update_db.sql | 31 ++++ .../OrganizationProxy.cs | 156 +++++++++++++++++ .../HostedSolution/OrganizationController.cs | 161 ++++++++++++++++++ .../WebsitePanel.EnterpriseServer.Code.csproj | 19 ++- .../packages.config | 5 + .../WebsitePanel.EnterpriseServer/Web.config | 4 + .../esOrganizations.asmx.cs | 14 ++ .../Config/Entities/SessionKeysCollection.cs | 2 +- .../WebConfigSections/SessionKeysElement.cs | 2 +- .../SmsAuthenticationService.cs | 3 + .../Controllers/AccountController.cs | 33 ++-- .../WebsitePanel_SharedResources.ascx.resx | 7 +- .../SettingsUserPasswordResetLetter.ascx.resx | 6 + .../OrganizationUserResetPassword.ascx.resx | 12 ++ .../OrganizationUserResetPassword.ascx | 97 +++++++---- .../OrganizationUserResetPassword.ascx.cs | 24 ++- ...nizationUserResetPassword.ascx.designer.cs | 90 ++++++++++ .../SettingsUserPasswordResetLetter.ascx | 15 ++ .../SettingsUserPasswordResetLetter.ascx.cs | 6 + ...gsUserPasswordResetLetter.ascx.designer.cs | 36 ++++ .../Sources/packages/repositories.config | 1 + 21 files changed, 664 insertions(+), 60 deletions(-) create mode 100644 WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/packages.config diff --git a/WebsitePanel/Database/update_db.sql b/WebsitePanel/Database/update_db.sql index 9fa58a77..2df1f2da 100644 --- a/WebsitePanel/Database/update_db.sql +++ b/WebsitePanel/Database/update_db.sql @@ -10029,6 +10029,37 @@ UPDATE [dbo].[UserSettings] SET [PropertyValue] = @UserPasswordResetLetterTextBo GO + + +DECLARE @UserPasswordResetSMSBody nvarchar(2500) + +Set @UserPasswordResetSMSBody = N'Password reset link: +#passwordResetLink# +' + +IF NOT EXISTS (SELECT * FROM [dbo].[UserSettings] WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetLetter' AND [PropertyName]= N'PasswordResetLinkSmsBody' ) +BEGIN +INSERT [dbo].[UserSettings] ([UserID], [SettingsName], [PropertyName], [PropertyValue]) VALUES (1, N'UserPasswordResetLetter', N'PasswordResetLinkSmsBody', @UserPasswordResetSMSBody) +END +ELSE +UPDATE [dbo].[UserSettings] SET [PropertyValue] = @UserPasswordResetSMSBody WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetLetter' AND [PropertyName]= N'PasswordResetLinkSmsBody' +GO + + +DECLARE @UserPasswordPincodeSMSBody nvarchar(2500) + +Set @UserPasswordPincodeSMSBody = N' +Your password reset pincode: +#passwordResetPincode#' + +IF NOT EXISTS (SELECT * FROM [dbo].[UserSettings] WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetLetter' AND [PropertyName]= N'PasswordResetPincodeSmsBody' ) +BEGIN +INSERT [dbo].[UserSettings] ([UserID], [SettingsName], [PropertyName], [PropertyValue]) VALUES (1, N'UserPasswordResetLetter', N'PasswordResetPincodeSmsBody', @UserPasswordPincodeSMSBody) +END +ELSE +UPDATE [dbo].[UserSettings] SET [PropertyValue] = @UserPasswordPincodeSMSBody WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetLetter' AND [PropertyName]= N'PasswordResetPincodeSmsBody' +GO + -- Exchange setup EMAIL TEMPLATE diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/OrganizationProxy.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/OrganizationProxy.cs index 9ab83269..fbafa0aa 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/OrganizationProxy.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/OrganizationProxy.cs @@ -82,6 +82,10 @@ namespace WebsitePanel.EnterpriseServer.HostedSolution { private System.Threading.SendOrPostCallback GetUserGeneralSettingsWithExtraDataOperationCompleted; + private System.Threading.SendOrPostCallback SendResetUserPasswordLinkSmsOperationCompleted; + + private System.Threading.SendOrPostCallback SendResetUserPasswordPincodeSmsOperationCompleted; + private System.Threading.SendOrPostCallback AddOrganizationDomainOperationCompleted; private System.Threading.SendOrPostCallback ChangeOrganizationDomainTypeOperationCompleted; @@ -234,6 +238,12 @@ namespace WebsitePanel.EnterpriseServer.HostedSolution { /// public event GetUserGeneralSettingsWithExtraDataCompletedEventHandler GetUserGeneralSettingsWithExtraDataCompleted; + /// + public event SendResetUserPasswordLinkSmsCompletedEventHandler SendResetUserPasswordLinkSmsCompleted; + + /// + public event SendResetUserPasswordPincodeSmsCompletedEventHandler SendResetUserPasswordPincodeSmsCompleted; + /// public event AddOrganizationDomainCompletedEventHandler AddOrganizationDomainCompleted; @@ -1359,6 +1369,100 @@ namespace WebsitePanel.EnterpriseServer.HostedSolution { } } + /// + [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/SendResetUserPasswordLinkSms", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] + public ResultObject SendResetUserPasswordLinkSms(int itemId, int accountId, string reason, string phoneTo) { + object[] results = this.Invoke("SendResetUserPasswordLinkSms", new object[] { + itemId, + accountId, + reason, + phoneTo}); + return ((ResultObject)(results[0])); + } + + /// + public System.IAsyncResult BeginSendResetUserPasswordLinkSms(int itemId, int accountId, string reason, string phoneTo, System.AsyncCallback callback, object asyncState) { + return this.BeginInvoke("SendResetUserPasswordLinkSms", new object[] { + itemId, + accountId, + reason, + phoneTo}, callback, asyncState); + } + + /// + public ResultObject EndSendResetUserPasswordLinkSms(System.IAsyncResult asyncResult) { + object[] results = this.EndInvoke(asyncResult); + return ((ResultObject)(results[0])); + } + + /// + public void SendResetUserPasswordLinkSmsAsync(int itemId, int accountId, string reason, string phoneTo) { + this.SendResetUserPasswordLinkSmsAsync(itemId, accountId, reason, phoneTo, null); + } + + /// + public void SendResetUserPasswordLinkSmsAsync(int itemId, int accountId, string reason, string phoneTo, object userState) { + if ((this.SendResetUserPasswordLinkSmsOperationCompleted == null)) { + this.SendResetUserPasswordLinkSmsOperationCompleted = new System.Threading.SendOrPostCallback(this.OnSendResetUserPasswordLinkSmsOperationCompleted); + } + this.InvokeAsync("SendResetUserPasswordLinkSms", new object[] { + itemId, + accountId, + reason, + phoneTo}, this.SendResetUserPasswordLinkSmsOperationCompleted, userState); + } + + private void OnSendResetUserPasswordLinkSmsOperationCompleted(object arg) { + if ((this.SendResetUserPasswordLinkSmsCompleted != null)) { + System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg)); + this.SendResetUserPasswordLinkSmsCompleted(this, new SendResetUserPasswordLinkSmsCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState)); + } + } + + /// + [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/SendResetUserPasswordPincodeSms", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] + public ResultObject SendResetUserPasswordPincodeSms(System.Guid token, string phoneTo) { + object[] results = this.Invoke("SendResetUserPasswordPincodeSms", new object[] { + token, + phoneTo}); + return ((ResultObject)(results[0])); + } + + /// + public System.IAsyncResult BeginSendResetUserPasswordPincodeSms(System.Guid token, string phoneTo, System.AsyncCallback callback, object asyncState) { + return this.BeginInvoke("SendResetUserPasswordPincodeSms", new object[] { + token, + phoneTo}, callback, asyncState); + } + + /// + public ResultObject EndSendResetUserPasswordPincodeSms(System.IAsyncResult asyncResult) { + object[] results = this.EndInvoke(asyncResult); + return ((ResultObject)(results[0])); + } + + /// + public void SendResetUserPasswordPincodeSmsAsync(System.Guid token, string phoneTo) { + this.SendResetUserPasswordPincodeSmsAsync(token, phoneTo, null); + } + + /// + public void SendResetUserPasswordPincodeSmsAsync(System.Guid token, string phoneTo, object userState) { + if ((this.SendResetUserPasswordPincodeSmsOperationCompleted == null)) { + this.SendResetUserPasswordPincodeSmsOperationCompleted = new System.Threading.SendOrPostCallback(this.OnSendResetUserPasswordPincodeSmsOperationCompleted); + } + this.InvokeAsync("SendResetUserPasswordPincodeSms", new object[] { + token, + phoneTo}, this.SendResetUserPasswordPincodeSmsOperationCompleted, userState); + } + + private void OnSendResetUserPasswordPincodeSmsOperationCompleted(object arg) { + if ((this.SendResetUserPasswordPincodeSmsCompleted != null)) { + System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg)); + this.SendResetUserPasswordPincodeSmsCompleted(this, new SendResetUserPasswordPincodeSmsCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState)); + } + } + /// [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/AddOrganizationDomain", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] public int AddOrganizationDomain(int itemId, string domainName) { @@ -3891,6 +3995,58 @@ namespace WebsitePanel.EnterpriseServer.HostedSolution { } } + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] + public delegate void SendResetUserPasswordLinkSmsCompletedEventHandler(object sender, SendResetUserPasswordLinkSmsCompletedEventArgs e); + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + public partial class SendResetUserPasswordLinkSmsCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs { + + private object[] results; + + internal SendResetUserPasswordLinkSmsCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) : + base(exception, cancelled, userState) { + this.results = results; + } + + /// + public ResultObject Result { + get { + this.RaiseExceptionIfNecessary(); + return ((ResultObject)(this.results[0])); + } + } + } + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] + public delegate void SendResetUserPasswordPincodeSmsCompletedEventHandler(object sender, SendResetUserPasswordPincodeSmsCompletedEventArgs e); + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + public partial class SendResetUserPasswordPincodeSmsCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs { + + private object[] results; + + internal SendResetUserPasswordPincodeSmsCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) : + base(exception, cancelled, userState) { + this.results = results; + } + + /// + public ResultObject Result { + get { + this.RaiseExceptionIfNecessary(); + return ((ResultObject)(this.results[0])); + } + } + } + /// [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] public delegate void AddOrganizationDomainCompletedEventHandler(object sender, AddOrganizationDomainCompletedEventArgs e); diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/HostedSolution/OrganizationController.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/HostedSolution/OrganizationController.cs index d22a81c2..5fdbd9d7 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/HostedSolution/OrganizationController.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/HostedSolution/OrganizationController.cs @@ -30,10 +30,13 @@ using System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; +using System.Configuration; using System.Data; +using System.Globalization; using System.Net.Mail; using System.Text; using System.Threading.Tasks; +using Twilio; using WebsitePanel.EnterpriseServer.Code.HostedSolution; using WebsitePanel.EnterpriseServer.Code.SharePoint; using WebsitePanel.EnterpriseServer.Extensions; @@ -1560,6 +1563,162 @@ namespace WebsitePanel.EnterpriseServer return expiredUsersDb; } + public static ResultObject SendResetUserPasswordLinkSms(int itemId, int accountId, string reason, + string phoneTo = null) + { + var result = TaskManager.StartResultTask("ORGANIZATION", "SEND_USER_PASSWORD_RESET_SMS", + itemId); + + try + { + + // load organization + Organization org = GetOrganization(itemId); + + if (org == null) + { + throw new Exception(string.Format("Organization not found (ItemId = {0})", itemId)); + } + + UserInfo owner = PackageController.GetPackageOwner(org.PackageId); + OrganizationUser user = OrganizationController.GetUserGeneralSettingsWithExtraData(itemId, accountId); + + user.ItemId = itemId; + + if (string.IsNullOrEmpty(phoneTo)) + { + phoneTo = user.MobilePhone; + } + + UserSettings settings = UserController.GetUserSettings(owner.UserId, + UserSettings.USER_PASSWORD_RESET_LETTER); + + + string body = settings["PasswordResetLinkSmsBody"]; + + var items = new Hashtable(); + + items["passwordResetLink"] = GenerateUserPasswordResetLink(user.ItemId, user.AccountId); + + body = PackageController.EvaluateTemplate(body, items); + + TaskManager.Write("Organization ID : " + user.ItemId); + TaskManager.Write("Account : " + user.DisplayName); + TaskManager.Write("Reason : " + reason); + TaskManager.Write("SmsTo : " + phoneTo); + + // send Sms message + var response = SendSms(phoneTo, body); + + if (response.RestException != null) + { + throw new Exception(response.RestException.Message); + } + } + catch (Exception ex) + { + TaskManager.WriteError(ex); + TaskManager.CompleteResultTask(result); + result.AddError("", ex); + return result; + } + + TaskManager.CompleteResultTask(); + return result; + } + + public static ResultObject SendResetUserPasswordPincodeSms(Guid token, string phoneTo = null) + { + var result = TaskManager.StartResultTask("ORGANIZATION", "SEND_USER_PASSWORD_RESET_SMS_PINCODE"); + + try + { + var accessToken = OrganizationController.GetAccessToken(token, AccessTokenTypes.PasswrodReset); + + if (accessToken == null) + { + throw new Exception(string.Format("Access token not found")); + } + + // load organization + Organization org = GetOrganization(accessToken.ItemId); + + if (org == null) + { + throw new Exception(string.Format("Organization not found")); + } + + UserInfo owner = PackageController.GetPackageOwner(org.PackageId); + OrganizationUser user = OrganizationController.GetUserGeneralSettingsWithExtraData(accessToken.ItemId, + accessToken.AccountId); + + if (string.IsNullOrEmpty(phoneTo)) + { + phoneTo = user.MobilePhone; + } + + UserSettings settings = UserController.GetUserSettings(owner.UserId, UserSettings.USER_PASSWORD_RESET_LETTER); + + string body = settings["PasswordResetPincodeSmsBody"]; + + var items = new Hashtable(); + + var pincode = GeneratePincode(); + + items["passwordResetPincode"] = pincode; + + body = PackageController.EvaluateTemplate(body, items); + + TaskManager.Write("Organization ID : " + user.ItemId); + TaskManager.Write("Account : " + user.DisplayName); + TaskManager.Write("SmsTo : " + phoneTo); + + // send Sms message + var response = SendSms(phoneTo, body); + + if (response.RestException != null) + { + throw new Exception(response.RestException.Message); + } + + SetAccessTokenResponse(token, pincode); + } + catch (Exception ex) + { + TaskManager.WriteError(ex); + TaskManager.CompleteResultTask(result); + result.AddError("", ex); + return result; + } + + TaskManager.CompleteResultTask(); + return result; + } + + private static string GeneratePincode() + { + var random = new Random(Guid.NewGuid().GetHashCode()); + + return random.Next(10000, 99999).ToString(CultureInfo.InvariantCulture); + } + + private static TwilioRestClient GetTwilioRestClient() + { + string accountSid = ConfigurationManager.AppSettings["WebsitePanel.Twilio.AccountSid"]; + string authToken = ConfigurationManager.AppSettings["WebsitePanel.Twilio.AuthorizationToken"]; + + return new TwilioRestClient(accountSid, authToken); + } + + private static SMSMessage SendSms(string to, string body) + { + var client = GetTwilioRestClient(); + + string phoneFrom = ConfigurationManager.AppSettings["WebsitePanel.Twilio.PhoneFrom"]; + + return client.SendSmsMessage(phoneFrom, to, body); + } + /// /// Send reset user password email /// @@ -1583,6 +1742,8 @@ namespace WebsitePanel.EnterpriseServer UserInfo owner = PackageController.GetPackageOwner(org.PackageId); OrganizationUser user = OrganizationController.GetUserGeneralSettingsWithExtraData(itemId, accountId); + user.ItemId = itemId; + if (string.IsNullOrEmpty(mailTo)) { mailTo = user.PrimaryEmailAddress; diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/WebsitePanel.EnterpriseServer.Code.csproj b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/WebsitePanel.EnterpriseServer.Code.csproj index 7cf712ca..9fa34343 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/WebsitePanel.EnterpriseServer.Code.csproj +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/WebsitePanel.EnterpriseServer.Code.csproj @@ -12,6 +12,8 @@ WebsitePanel.EnterpriseServer.Code v4.0 512 + ..\ + true true @@ -42,6 +44,9 @@ ..\..\Lib\Microsoft.Web.Services3.dll True + + ..\packages\RestSharp.105.0.1\lib\net4\RestSharp.dll + @@ -55,6 +60,9 @@ + + ..\packages\Twilio.3.6.29\lib\3.5\Twilio.Api.dll + False ..\..\Bin\WebsitePanel.EnterpriseServer.Base.dll @@ -202,8 +210,17 @@ WebsitePanel.Whois - + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esOrganizations.asmx.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esOrganizations.asmx.cs index a9157367..9ce4e663 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esOrganizations.asmx.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esOrganizations.asmx.cs @@ -191,6 +191,20 @@ namespace WebsitePanel.EnterpriseServer return OrganizationController.GetUserGeneralSettingsWithExtraData(itemId, accountId); } + [WebMethod] + public ResultObject SendResetUserPasswordLinkSms(int itemId, int accountId, string reason, string phoneTo = null) + { + return OrganizationController.SendResetUserPasswordLinkSms(itemId, accountId, reason, phoneTo); + } + + + [WebMethod] + public ResultObject SendResetUserPasswordPincodeSms(Guid token, string phoneTo = null) + { + return OrganizationController.SendResetUserPasswordPincodeSms(token, phoneTo); + } + + #endregion #region Domains diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/SessionKeysCollection.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/SessionKeysCollection.cs index 1cbfa2e9..32309430 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/SessionKeysCollection.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/SessionKeysCollection.cs @@ -70,7 +70,7 @@ namespace WebsitePanel.WebDav.Core.Config.Entities get { SessionKeysElement sessionKey = - _sessionKeys.FirstOrDefault(x => x.Key == SessionKeysElement.PassswordResetSmsKey); + _sessionKeys.FirstOrDefault(x => x.Key == SessionKeysElement.PasswordResetSmsKey); return sessionKey != null ? sessionKey.Value : null; } } diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/SessionKeysElement.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/SessionKeysElement.cs index efeea291..07b43395 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/SessionKeysElement.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/SessionKeysElement.cs @@ -12,7 +12,7 @@ namespace WebsitePanel.WebDav.Core.Config.WebConfigSections public const string WebDavManagerKey = "WebDavManagerSessionKey"; public const string UserGroupsKey = "UserGroupsKey"; public const string WebDavRootFolderPermissionsKey = "WebDavRootFolderPermissionsKey"; - public const string PassswordResetSmsKey = "PassswordResetSmsKey"; + public const string PasswordResetSmsKey = "PasswordResetSmsKey"; public const string ResourseRenderCountKey = "ResourseRenderCountSessionKey"; public const string ItemIdSessionKey = "ItemId"; public const string OwaEditFoldersSessionKey = "OwaEditFoldersSession"; diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Security/Authentication/SmsAuthenticationService.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Security/Authentication/SmsAuthenticationService.cs index 10cba6a1..6b5c714f 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Security/Authentication/SmsAuthenticationService.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Security/Authentication/SmsAuthenticationService.cs @@ -1,5 +1,6 @@ using System; using System.Globalization; +using log4net; using WebsitePanel.WebDav.Core.Config; using WebsitePanel.WebDav.Core.Interfaces.Security; using WebsitePanel.WebDav.Core.Interfaces.Services; @@ -9,10 +10,12 @@ namespace WebsitePanel.WebDav.Core.Security.Authentication public class SmsAuthenticationService : ISmsAuthenticationService { private ISmsDistributionService _smsService; + private readonly ILog Log; public SmsAuthenticationService(ISmsDistributionService smsService) { _smsService = smsService; + Log = LogManager.GetLogger(this.GetType()); } public bool VerifyResponse( Guid token, string response) diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/AccountController.cs b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/AccountController.cs index 65bdef13..38b298db 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/AccountController.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/AccountController.cs @@ -4,6 +4,7 @@ using System.Net; using System.Web.Mvc; using System.Web.Routing; using AutoMapper; +using log4net; using WebsitePanel.Providers.HostedSolution; using WebsitePanel.WebDav.Core.Config; using WebsitePanel.WebDav.Core.Security.Authentication; @@ -27,12 +28,15 @@ namespace WebsitePanel.WebDavPortal.Controllers private readonly ICryptography _cryptography; private readonly IAuthenticationService _authenticationService; private readonly ISmsAuthenticationService _smsAuthService; + private readonly ILog Log; public AccountController(ICryptography cryptography, IAuthenticationService authenticationService, ISmsAuthenticationService smsAuthService) { _cryptography = cryptography; _authenticationService = authenticationService; _smsAuthService = smsAuthService; + + Log = LogManager.GetLogger(this.GetType()); } [HttpGet] @@ -205,11 +209,15 @@ namespace WebsitePanel.WebDavPortal.Controllers return View(model); } - if (accessToken.IsSmsSent == false) - { - var user = WspContext.Services.Organizations.GetUserGeneralSettings(accessToken.ItemId, accessToken.AccountId); - if (SendPasswordResetSms(accessToken.AccessTokenGuid, user.MobilePhone)) + if (accessToken != null && accessToken.IsSmsSent == false) + { + var user = WspContext.Services.Organizations.GetUserGeneralSettings(accessToken.ItemId, + accessToken.AccountId); + + var result = WspContext.Services.Organizations.SendResetUserPasswordPincodeSms(token, user.MobilePhone); + + if (result.IsSuccess) { AddMessage(MessageType.Success, Resources.Messages.SmsWasSent); } @@ -308,8 +316,10 @@ namespace WebsitePanel.WebDavPortal.Controllers var user = WspContext.Services.Organizations.GetUserGeneralSettings(accessToken.ItemId, accessToken.AccountId); + var result = WspContext.Services.Organizations.SendResetUserPasswordPincodeSms(accessToken.AccessTokenGuid, + user.MobilePhone); - if (SendPasswordResetSms(accessToken.AccessTokenGuid, user.MobilePhone)) + if (result.IsSuccess) { AddMessage(MessageType.Success, Resources.Messages.SmsWasSent); } @@ -323,19 +333,6 @@ namespace WebsitePanel.WebDavPortal.Controllers #region Helpers - private bool SendPasswordResetSms(Guid token, string mobilePhone) - { - var response = _smsAuthService.SendRequestMessage(mobilePhone); - - if (string.IsNullOrEmpty(response)) - { - return false; - } - WspContext.Services.Organizations.SetAccessTokenResponse(token, response); - - return true; - } - private UserProfile GetUserProfileModel(int itemId, int accountId) { var user = WspContext.Services.Organizations.GetUserGeneralSettingsWithExtraData(itemId, accountId); 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 37177986..ba7b79c2 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/App_GlobalResources/WebsitePanel_SharedResources.ascx.resx +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/App_GlobalResources/WebsitePanel_SharedResources.ascx.resx @@ -5131,7 +5131,6 @@ Allow user to Start, Turn off VPS - Virtual Private Servers 2012 @@ -5198,7 +5197,6 @@ Allow user to Start, Turn off VPS - Error creating CheckPoint @@ -5784,7 +5782,7 @@ View session error - + Control session error @@ -5805,4 +5803,7 @@ Unable to load password settings + + Sms was not sent. + \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/App_LocalResources/SettingsUserPasswordResetLetter.ascx.resx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/App_LocalResources/SettingsUserPasswordResetLetter.ascx.resx index d0758d63..559ba6bc 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/App_LocalResources/SettingsUserPasswordResetLetter.ascx.resx +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/App_LocalResources/SettingsUserPasswordResetLetter.ascx.resx @@ -141,6 +141,12 @@ No Changes Text Body: + + Password Reset Link Sms Body: + + + Password Reset Link Pincode Body: + Priority: diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/App_LocalResources/OrganizationUserResetPassword.ascx.resx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/App_LocalResources/OrganizationUserResetPassword.ascx.resx index adb7dc30..f9dc009b 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/App_LocalResources/OrganizationUserResetPassword.ascx.resx +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/App_LocalResources/OrganizationUserResetPassword.ascx.resx @@ -123,10 +123,22 @@ Email: + + Mobile + Reason: + + Send to: + Reset Password + + Email + + + Mobile + \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/OrganizationUserResetPassword.ascx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/OrganizationUserResetPassword.ascx index 7da8a076..b4b70839 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/OrganizationUserResetPassword.ascx +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/OrganizationUserResetPassword.ascx @@ -4,42 +4,69 @@
-
-
-
-
-
-
- - - - +
+
+
+
+
+
+ + + -
-
- - - - - - - - - -
- - - -
- - -
- -
- -
-
-
-
-
+
+ + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+ + + + +
+ + + + +
+ + + +
+ +
+
+ +
+ +
+
+
+
+
diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/OrganizationUserResetPassword.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/OrganizationUserResetPassword.ascx.cs index 90a5508a..6fc86dd2 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/OrganizationUserResetPassword.ascx.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/OrganizationUserResetPassword.ascx.cs @@ -26,6 +26,8 @@ namespace WebsitePanel.Portal.ExchangeServer litDisplayName.Text = PortalAntiXSS.Encode(user.DisplayName); txtEmailAddress.Text = user.PrimaryEmailAddress; + + txtMobile.Text = user.MobilePhone; } protected void btnResetPassoword_Click(object sender, EventArgs e) @@ -35,11 +37,31 @@ namespace WebsitePanel.Portal.ExchangeServer return; } - ES.Services.Organizations.SendResetUserPasswordEmail(PanelRequest.ItemID,PanelRequest.AccountID, txtReason.Text, txtEmailAddress.Text); + if (rbtnEmail.Checked) + { + ES.Services.Organizations.SendResetUserPasswordEmail(PanelRequest.ItemID,PanelRequest.AccountID, txtReason.Text, txtEmailAddress.Text); + } + else + { + var result = ES.Services.Organizations.SendResetUserPasswordLinkSms(PanelRequest.ItemID, PanelRequest.AccountID, txtReason.Text, txtMobile.Text); + + if (!result.IsSuccess) + { + ShowErrorMessage("SEND_USER_PASSWORD_RESET_SMS"); + + return; + } + } Response.Redirect(PortalUtils.EditUrl("ItemID", PanelRequest.ItemID.ToString(), (PanelRequest.Context == "Mailbox") ? "mailboxes" : "users", "SpaceID=" + PanelSecurity.PackageId)); } + + protected void SendToGroupCheckedChanged(object sender, EventArgs e) + { + EmailRow.Visible = rbtnEmail.Checked; + MobileRow.Visible = !rbtnEmail.Checked; + } } } \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/OrganizationUserResetPassword.ascx.designer.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/OrganizationUserResetPassword.ascx.designer.cs index 5b263a84..7c1339cb 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/OrganizationUserResetPassword.ascx.designer.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/OrganizationUserResetPassword.ascx.designer.cs @@ -39,6 +39,51 @@ namespace WebsitePanel.Portal.ExchangeServer { /// protected global::System.Web.UI.WebControls.Literal litDisplayName; + /// + /// PasswrodResetUpdatePanel control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.UpdatePanel PasswrodResetUpdatePanel; + + /// + /// locSendTo control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Localize locSendTo; + + /// + /// rbtnEmail control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.RadioButton rbtnEmail; + + /// + /// rbtnMobile control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.RadioButton rbtnMobile; + + /// + /// EmailRow control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.HtmlControls.HtmlTableRow EmailRow; + /// /// locEmailAddress control. /// @@ -75,6 +120,51 @@ namespace WebsitePanel.Portal.ExchangeServer { /// protected global::System.Web.UI.WebControls.RegularExpressionValidator regexEmailValid; + /// + /// MobileRow control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.HtmlControls.HtmlTableRow MobileRow; + + /// + /// locMobile control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Localize locMobile; + + /// + /// txtMobile control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.TextBox txtMobile; + + /// + /// valMobile control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.RequiredFieldValidator valMobile; + + /// + /// regexMobileValid control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.RegularExpressionValidator regexMobileValid; + /// /// locReason control. /// diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SettingsUserPasswordResetLetter.ascx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SettingsUserPasswordResetLetter.ascx index 48251fb0..53935cdd 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SettingsUserPasswordResetLetter.ascx +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SettingsUserPasswordResetLetter.ascx @@ -41,5 +41,20 @@ + + +

+ + + + + + tr> +

+ + + + + \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SettingsUserPasswordResetLetter.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SettingsUserPasswordResetLetter.ascx.cs index 12cb669b..597d2d4e 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SettingsUserPasswordResetLetter.ascx.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SettingsUserPasswordResetLetter.ascx.cs @@ -18,6 +18,9 @@ namespace WebsitePanel.Portal txtHtmlBody.Text = settings["HtmlBody"]; txtTextBody.Text = settings["TextBody"]; txtLogoUrl.Text = settings["LogoUrl"]; + + txtBodyPasswordResetLinkSmsBody.Text = settings["PasswordResetLinkSmsBody"]; + txtPasswordResetPincodeSmsBody.Text = settings["PasswordResetPincodeSmsBody"]; } public void SaveSettings(UserSettings settings) @@ -28,6 +31,9 @@ namespace WebsitePanel.Portal settings["HtmlBody"] = txtHtmlBody.Text; settings["TextBody"] = txtTextBody.Text; settings["LogoUrl"] = txtLogoUrl.Text; + + settings["PasswordResetLinkSmsBody"]= txtBodyPasswordResetLinkSmsBody.Text; + settings["PasswordResetPincodeSmsBody"] =txtPasswordResetPincodeSmsBody.Text; } } } \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SettingsUserPasswordResetLetter.ascx.designer.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SettingsUserPasswordResetLetter.ascx.designer.cs index 84c322e1..e4d4f21f 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SettingsUserPasswordResetLetter.ascx.designer.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SettingsUserPasswordResetLetter.ascx.designer.cs @@ -119,5 +119,41 @@ namespace WebsitePanel.Portal { /// To modify move field declaration from designer file to code-behind file. /// protected global::System.Web.UI.WebControls.TextBox txtTextBody; + + /// + /// lblPasswordResetLinkSmsBody control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Label lblPasswordResetLinkSmsBody; + + /// + /// txtBodyPasswordResetLinkSmsBody control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.TextBox txtBodyPasswordResetLinkSmsBody; + + /// + /// lblPasswordResetPincodeSmsBody control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Label lblPasswordResetPincodeSmsBody; + + /// + /// txtPasswordResetPincodeSmsBody control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.TextBox txtPasswordResetPincodeSmsBody; } } diff --git a/WebsitePanel/Sources/packages/repositories.config b/WebsitePanel/Sources/packages/repositories.config index dd410324..071af726 100644 --- a/WebsitePanel/Sources/packages/repositories.config +++ b/WebsitePanel/Sources/packages/repositories.config @@ -1,5 +1,6 @@  +