password reset link sms added

This commit is contained in:
vfedosevich 2015-04-24 06:19:11 -07:00
parent 9c9fad9ba7
commit 7bd6628bea
21 changed files with 664 additions and 60 deletions

View file

@ -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

View file

@ -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 {
/// <remarks/>
public event GetUserGeneralSettingsWithExtraDataCompletedEventHandler GetUserGeneralSettingsWithExtraDataCompleted;
/// <remarks/>
public event SendResetUserPasswordLinkSmsCompletedEventHandler SendResetUserPasswordLinkSmsCompleted;
/// <remarks/>
public event SendResetUserPasswordPincodeSmsCompletedEventHandler SendResetUserPasswordPincodeSmsCompleted;
/// <remarks/>
public event AddOrganizationDomainCompletedEventHandler AddOrganizationDomainCompleted;
@ -1359,6 +1369,100 @@ namespace WebsitePanel.EnterpriseServer.HostedSolution {
}
}
/// <remarks/>
[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]));
}
/// <remarks/>
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);
}
/// <remarks/>
public ResultObject EndSendResetUserPasswordLinkSms(System.IAsyncResult asyncResult) {
object[] results = this.EndInvoke(asyncResult);
return ((ResultObject)(results[0]));
}
/// <remarks/>
public void SendResetUserPasswordLinkSmsAsync(int itemId, int accountId, string reason, string phoneTo) {
this.SendResetUserPasswordLinkSmsAsync(itemId, accountId, reason, phoneTo, null);
}
/// <remarks/>
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));
}
}
/// <remarks/>
[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]));
}
/// <remarks/>
public System.IAsyncResult BeginSendResetUserPasswordPincodeSms(System.Guid token, string phoneTo, System.AsyncCallback callback, object asyncState) {
return this.BeginInvoke("SendResetUserPasswordPincodeSms", new object[] {
token,
phoneTo}, callback, asyncState);
}
/// <remarks/>
public ResultObject EndSendResetUserPasswordPincodeSms(System.IAsyncResult asyncResult) {
object[] results = this.EndInvoke(asyncResult);
return ((ResultObject)(results[0]));
}
/// <remarks/>
public void SendResetUserPasswordPincodeSmsAsync(System.Guid token, string phoneTo) {
this.SendResetUserPasswordPincodeSmsAsync(token, phoneTo, null);
}
/// <remarks/>
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));
}
}
/// <remarks/>
[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 {
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")]
public delegate void SendResetUserPasswordLinkSmsCompletedEventHandler(object sender, SendResetUserPasswordLinkSmsCompletedEventArgs e);
/// <remarks/>
[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;
}
/// <remarks/>
public ResultObject Result {
get {
this.RaiseExceptionIfNecessary();
return ((ResultObject)(this.results[0]));
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")]
public delegate void SendResetUserPasswordPincodeSmsCompletedEventHandler(object sender, SendResetUserPasswordPincodeSmsCompletedEventArgs e);
/// <remarks/>
[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;
}
/// <remarks/>
public ResultObject Result {
get {
this.RaiseExceptionIfNecessary();
return ((ResultObject)(this.results[0]));
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")]
public delegate void AddOrganizationDomainCompletedEventHandler(object sender, AddOrganizationDomainCompletedEventArgs e);

View file

@ -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<ResultObject>("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<ResultObject>("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);
}
/// <summary>
/// Send reset user password email
/// </summary>
@ -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;

View file

@ -12,6 +12,8 @@
<AssemblyName>WebsitePanel.EnterpriseServer.Code</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<RestorePackages>true</RestorePackages>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -42,6 +44,9 @@
<HintPath>..\..\Lib\Microsoft.Web.Services3.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="RestSharp">
<HintPath>..\packages\RestSharp.105.0.1\lib\net4\RestSharp.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
@ -55,6 +60,9 @@
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="Twilio.Api">
<HintPath>..\packages\Twilio.3.6.29\lib\3.5\Twilio.Api.dll</HintPath>
</Reference>
<Reference Include="WebsitePanel.EnterpriseServer.Base, Version=2.1.0.1, Culture=neutral, PublicKeyToken=da8782a6fc4d0081, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\Bin\WebsitePanel.EnterpriseServer.Base.dll</HintPath>
@ -202,8 +210,17 @@
<Name>WebsitePanel.Whois</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup />
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>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}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="RestSharp" version="105.0.1" targetFramework="net40" />
<package id="Twilio" version="3.6.29" targetFramework="net40" />
</packages>

View file

@ -20,6 +20,10 @@
<add key="WebsitePanel.EnterpriseServer.ServerRequestTimeout" value="3600"/>
<add key="WebsitePanel.AltConnectionString" value="ConnectionString"/>
<add key="WebsitePanel.AltCryptoKey" value="CryptoKey"/>
<add key="WebsitePanel.Twilio.AccountSid" value="1"/>
<add key="WebsitePanel.Twilio.AuthorizationToken" value="2"/>
<add key="WebsitePanel.Twilio.PhoneFrom" value="+15005550006"/>
</appSettings>
<system.web>
<!-- Disable any authentication -->

View file

@ -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

View file

@ -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;
}
}

View file

@ -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";

View file

@ -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)

View file

@ -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);

View file

@ -5131,7 +5131,6 @@
<data name="Quota.VPSForPC.StartShutdownAllowed" xml:space="preserve">
<value>Allow user to Start, Turn off VPS</value>
</data>
<data name="ResourceGroup.VPS2012" xml:space="preserve">
<value>Virtual Private Servers 2012</value>
</data>
@ -5198,7 +5197,6 @@
<data name="Quota.VPS2012.StartShutdownAllowed" xml:space="preserve">
<value>Allow user to Start, Turn off VPS</value>
</data>
<data name="Error.CreateCheckPointError" xml:space="preserve">
<value>Error creating CheckPoint</value>
</data>
@ -5805,4 +5803,7 @@
<data name="Error.UNABLETOLOADPASSWORDSETTINGS" xml:space="preserve">
<value>Unable to load password settings</value>
</data>
<data name="Error.SEND_USER_PASSWORD_RESET_SMS" xml:space="preserve">
<value>Sms was not sent.</value>
</data>
</root>

View file

@ -141,6 +141,12 @@
<data name="lblNoChangesTextBody.Text" xml:space="preserve">
<value>No Changes Text Body:</value>
</data>
<data name="lblPasswordResetLinkSmsBody.Text" xml:space="preserve">
<value>Password Reset Link Sms Body:</value>
</data>
<data name="lblPasswordResetPincodeSmsBody.Text" xml:space="preserve">
<value>Password Reset Link Pincode Body:</value>
</data>
<data name="lblPriority.Text" xml:space="preserve">
<value>Priority:</value>
</data>

View file

@ -123,10 +123,22 @@
<data name="locEmailAddress.Text" xml:space="preserve">
<value>Email:</value>
</data>
<data name="locMobile.Text" xml:space="preserve">
<value>Mobile</value>
</data>
<data name="locReason.Text" xml:space="preserve">
<value>Reason:</value>
</data>
<data name="locSendTo.Text" xml:space="preserve">
<value>Send to:</value>
</data>
<data name="locTitle.Text" xml:space="preserve">
<value>Reset Password</value>
</data>
<data name="rbtnEmail.Text" xml:space="preserve">
<value>Email</value>
</data>
<data name="rbtnMobile.Text" xml:space="preserve">
<value>Mobile</value>
</data>
</root>

View file

@ -17,17 +17,41 @@
</div>
<div class="FormBody">
<asp:UpdatePanel ID="PasswrodResetUpdatePanel" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="true">
<ContentTemplate>
<table>
<tr>
<td class="FormLabel150" valign="top"><asp:Localize ID="locEmailAddress" runat="server" meta:resourcekey="locEmailAddress" ></asp:Localize></td>
<td class="FormLabel150">
<asp:Localize ID="locSendTo" runat="server" meta:resourcekey="locSendTo" Text="Send to:"></asp:Localize></td>
<td class="FormRBtnL">
<asp:RadioButton ID="rbtnEmail" runat="server" meta:resourcekey="rbtnEmail" Text="Email" GroupName="SendToGroup" AutoPostBack="true" Checked="true" OnCheckedChanged="SendToGroupCheckedChanged" />
<asp:RadioButton ID="rbtnMobile" runat="server" meta:resourcekey="rbtnMobile" Text="Mobile" GroupName="SendToGroup" AutoPostBack="true" OnCheckedChanged="SendToGroupCheckedChanged" />
<br />
<br />
</td>
</tr>
<tr id="EmailRow" runat="server">
<td class="FormLabel150" valign="top">
<asp:Localize ID="locEmailAddress" runat="server" meta:resourcekey="locEmailAddress"></asp:Localize></td>
<td>
<asp:TextBox runat="server" ID="txtEmailAddress" CssClass="TextBox200"/>
<asp:TextBox runat="server" ID="txtEmailAddress" CssClass="TextBox200" />
<asp:RequiredFieldValidator ID="valEmailAddress" runat="server" ErrorMessage="*" ControlToValidate="txtEmailAddress" ValidationGroup="ResetUserPassword"></asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="regexEmailValid" runat="server" ValidationExpression="\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*" ValidationGroup="ResetUserPassword" ControlToValidate="txtEmailAddress" ErrorMessage="Invalid Email Format"></asp:RegularExpressionValidator>
</td>
</tr>
<tr id="MobileRow" runat="server" visible="False">
<td class="FormLabel150" valign="top">
<asp:Localize ID="locMobile" runat="server" meta:resourcekey="locMobile"></asp:Localize></td>
<td>
<asp:TextBox runat="server" ID="txtMobile" CssClass="TextBox200" />
<asp:RequiredFieldValidator ID="valMobile" runat="server" ErrorMessage="*" ControlToValidate="txtMobile" ValidationGroup="ResetUserPassword"></asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="regexMobileValid" runat="server" ValidationExpression="^\+?\d+$" ValidationGroup="ResetUserPassword" ControlToValidate="txtMobile" ErrorMessage="Invalid Mobile Format"></asp:RegularExpressionValidator>
</td>
</tr>
<tr>
<td class="FormLabel150"><asp:Localize ID="locReason" runat="server" meta:resourcekey="locReason" Text="Reason:"></asp:Localize></td>
<td class="FormLabel150">
<asp:Localize ID="locReason" runat="server" meta:resourcekey="locReason" Text="Reason:"></asp:Localize></td>
<td>
<asp:TextBox ID="txtReason" runat="server" CssClass="TextBox200" Rows="4" TextMode="MultiLine"></asp:TextBox>
<asp:RequiredFieldValidator ID="valReason" runat="server" ErrorMessage="*" ControlToValidate="txtReason" ValidationGroup="ResetUserPassword"></asp:RequiredFieldValidator>
@ -35,8 +59,11 @@
</tr>
</table>
</ContentTemplate>
</asp:UpdatePanel>
<div class="FormFooterClean">
<asp:Button id="btnResetPassoword" runat="server" Text="Send Password Reset Email" CssClass="Button1" meta:resourcekey="btnResetPassoword" ValidationGroup="ResetUserPassword" OnClick="btnResetPassoword_Click"></asp:Button>
<asp:Button ID="btnResetPassoword" runat="server" Text="Send Password Reset Email" CssClass="Button1" meta:resourcekey="btnResetPassoword" ValidationGroup="ResetUserPassword" OnClick="btnResetPassoword_Click"></asp:Button>
</div>
</div>
</div>

View file

@ -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;
}
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;
}
}
}

View file

@ -39,6 +39,51 @@ namespace WebsitePanel.Portal.ExchangeServer {
/// </remarks>
protected global::System.Web.UI.WebControls.Literal litDisplayName;
/// <summary>
/// PasswrodResetUpdatePanel control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.UpdatePanel PasswrodResetUpdatePanel;
/// <summary>
/// locSendTo control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Localize locSendTo;
/// <summary>
/// rbtnEmail control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.RadioButton rbtnEmail;
/// <summary>
/// rbtnMobile control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.RadioButton rbtnMobile;
/// <summary>
/// EmailRow control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.HtmlControls.HtmlTableRow EmailRow;
/// <summary>
/// locEmailAddress control.
/// </summary>
@ -75,6 +120,51 @@ namespace WebsitePanel.Portal.ExchangeServer {
/// </remarks>
protected global::System.Web.UI.WebControls.RegularExpressionValidator regexEmailValid;
/// <summary>
/// MobileRow control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.HtmlControls.HtmlTableRow MobileRow;
/// <summary>
/// locMobile control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Localize locMobile;
/// <summary>
/// txtMobile control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.TextBox txtMobile;
/// <summary>
/// valMobile control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.RequiredFieldValidator valMobile;
/// <summary>
/// regexMobileValid control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.RegularExpressionValidator regexMobileValid;
/// <summary>
/// locReason control.
/// </summary>

View file

@ -42,4 +42,19 @@
<asp:TextBox ID="txtTextBody" runat="server" Rows="15" TextMode="MultiLine" Width="680px" CssClass="NormalTextBox" Wrap="false"></asp:TextBox></td>
</tr>
<tr>
<td class="SubHead" colspan="2"><br /><br /><asp:Label ID="lblPasswordResetLinkSmsBody" runat="server" meta:resourcekey="lblPasswordResetLinkSmsBody" Text="Password Reset Link Sms Body:"></asp:Label></td>
</tr>
<tr>
<td class="Normal" colspan="2">
<asp:TextBox ID="txtBodyPasswordResetLinkSmsBody" runat="server" Rows="15" TextMode="MultiLine" Width="680px" CssClass="NormalTextBox" Wrap="false"></asp:TextBox></td>
</tr>
tr>
<td class="SubHead" colspan="2"><br /><br /><asp:Label ID="lblPasswordResetPincodeSmsBody" runat="server" meta:resourcekey="lblPasswordResetPincodeSmsBody" Text="Password Reset Link Pincode Body:"></asp:Label></td>
</tr>
<tr>
<td class="Normal" colspan="2">
<asp:TextBox ID="txtPasswordResetPincodeSmsBody" runat="server" Rows="15" TextMode="MultiLine" Width="680px" CssClass="NormalTextBox" Wrap="false"></asp:TextBox></td>
</tr>
</table>

View file

@ -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;
}
}
}

View file

@ -119,5 +119,41 @@ namespace WebsitePanel.Portal {
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.TextBox txtTextBody;
/// <summary>
/// lblPasswordResetLinkSmsBody control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Label lblPasswordResetLinkSmsBody;
/// <summary>
/// txtBodyPasswordResetLinkSmsBody control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.TextBox txtBodyPasswordResetLinkSmsBody;
/// <summary>
/// lblPasswordResetPincodeSmsBody control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Label lblPasswordResetPincodeSmsBody;
/// <summary>
/// txtPasswordResetPincodeSmsBody control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.TextBox txtPasswordResetPincodeSmsBody;
}
}

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<repositories>
<repository path="..\WebsitePanel.EnterpriseServer.Code\packages.config" />
<repository path="..\WebsitePanel.WebDav.Core\packages.config" />
<repository path="..\WebsitePanel.WebDavPortal\packages.config" />
<repository path="..\WebsitePanel.WebPortal\packages.config" />