diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/System/SystemSettings.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/System/SystemSettings.cs
index 7af8b4f3..d713ba88 100644
--- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/System/SystemSettings.cs
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/System/SystemSettings.cs
@@ -47,6 +47,14 @@ namespace WebsitePanel.EnterpriseServer
public const string PACKAGE_DISPLAY_SETTINGS = "PackageDisplaySettings";
public const string RDS_SETTINGS = "RdsSettings";
public const string WEBDAV_PORTAL_SETTINGS = "WebdavPortalSettings";
+ public const string TWILIO_SETTINGS = "TwilioSettings";
+
+
+ //Keys
+ public const string TWILIO_ACCOUNTSID_KEY = "TwilioAccountSid";
+ public const string TWILIO_AUTHTOKEN_KEY = "TwilioAuthToken";
+ public const string TWILIO_PHONEFROM_KEY = "TwilioPhoneFrom";
+
public const string WEBDAV_PASSWORD_RESET_ENABLED_KEY = "WebdavPswResetEnabled";
// key to access to wpi main & custom feed in wpi settings
diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/OrganizationProxy.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/OrganizationProxy.cs
index fbafa0aa..05baf043 100644
--- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/OrganizationProxy.cs
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/OrganizationProxy.cs
@@ -2648,21 +2648,23 @@ namespace WebsitePanel.EnterpriseServer.HostedSolution {
///
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/SendResetUserPasswordEmail", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
- public void SendResetUserPasswordEmail(int itemId, int accountId, string reason, string mailTo) {
+ public void SendResetUserPasswordEmail(int itemId, int accountId, string reason, string mailTo, bool finalStep) {
this.Invoke("SendResetUserPasswordEmail", new object[] {
itemId,
accountId,
reason,
- mailTo});
+ mailTo,
+ finalStep});
}
///
- public System.IAsyncResult BeginSendResetUserPasswordEmail(int itemId, int accountId, string reason, string mailTo, System.AsyncCallback callback, object asyncState) {
+ public System.IAsyncResult BeginSendResetUserPasswordEmail(int itemId, int accountId, string reason, string mailTo, bool finalStep, System.AsyncCallback callback, object asyncState) {
return this.BeginInvoke("SendResetUserPasswordEmail", new object[] {
itemId,
accountId,
reason,
- mailTo}, callback, asyncState);
+ mailTo,
+ finalStep}, callback, asyncState);
}
///
@@ -2671,12 +2673,12 @@ namespace WebsitePanel.EnterpriseServer.HostedSolution {
}
///
- public void SendResetUserPasswordEmailAsync(int itemId, int accountId, string reason, string mailTo) {
- this.SendResetUserPasswordEmailAsync(itemId, accountId, reason, mailTo, null);
+ public void SendResetUserPasswordEmailAsync(int itemId, int accountId, string reason, string mailTo, bool finalStep) {
+ this.SendResetUserPasswordEmailAsync(itemId, accountId, reason, mailTo, finalStep, null);
}
///
- public void SendResetUserPasswordEmailAsync(int itemId, int accountId, string reason, string mailTo, object userState) {
+ public void SendResetUserPasswordEmailAsync(int itemId, int accountId, string reason, string mailTo, bool finalStep, object userState) {
if ((this.SendResetUserPasswordEmailOperationCompleted == null)) {
this.SendResetUserPasswordEmailOperationCompleted = new System.Threading.SendOrPostCallback(this.OnSendResetUserPasswordEmailOperationCompleted);
}
@@ -2684,7 +2686,8 @@ namespace WebsitePanel.EnterpriseServer.HostedSolution {
itemId,
accountId,
reason,
- mailTo}, this.SendResetUserPasswordEmailOperationCompleted, userState);
+ mailTo,
+ finalStep}, this.SendResetUserPasswordEmailOperationCompleted, userState);
}
private void OnSendResetUserPasswordEmailOperationCompleted(object arg) {
diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/ExchangeServer/ExchangeServerController.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/ExchangeServer/ExchangeServerController.cs
index 47a17473..12ea3e0a 100644
--- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/ExchangeServer/ExchangeServerController.cs
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/ExchangeServer/ExchangeServerController.cs
@@ -2616,7 +2616,9 @@ namespace WebsitePanel.EnterpriseServer
items["AccountDomain"] = account.PrimaryEmailAddress.Substring(account.PrimaryEmailAddress.IndexOf("@") + 1);
items["DefaultDomain"] = org.DefaultDomain;
- var passwordResetUrl = OrganizationController.GenerateUserPasswordResetLink(account.ItemId, account.AccountId);
+ Guid token;
+
+ var passwordResetUrl = OrganizationController.GenerateUserPasswordResetLink(account.ItemId, account.AccountId,out token);
if (!string.IsNullOrEmpty(passwordResetUrl))
{
items["PswResetUrl"] = passwordResetUrl;
diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/HostedSolution/OrganizationController.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/HostedSolution/OrganizationController.cs
index 5fdbd9d7..2b3165f1 100644
--- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/HostedSolution/OrganizationController.cs
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/HostedSolution/OrganizationController.cs
@@ -1596,9 +1596,12 @@ namespace WebsitePanel.EnterpriseServer
string body = settings["PasswordResetLinkSmsBody"];
+ var pincode = GeneratePincode();
+ Guid token;
+
var items = new Hashtable();
- items["passwordResetLink"] = GenerateUserPasswordResetLink(user.ItemId, user.AccountId);
+ items["passwordResetLink"] = GenerateUserPasswordResetLink(user.ItemId, user.AccountId, out token, pincode);
body = PackageController.EvaluateTemplate(body, items);
@@ -1614,6 +1617,8 @@ namespace WebsitePanel.EnterpriseServer
{
throw new Exception(response.RestException.Message);
}
+
+ SetAccessTokenResponse(token, pincode);
}
catch (Exception ex)
{
@@ -1702,19 +1707,25 @@ namespace WebsitePanel.EnterpriseServer
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();
+ SystemSettings settings = SystemController.GetSystemSettingsInternal(SystemSettings.TWILIO_SETTINGS, false);
- string phoneFrom = ConfigurationManager.AppSettings["WebsitePanel.Twilio.PhoneFrom"];
+ if (settings == null)
+ {
+ throw new Exception("Twilio settings are not set");
+ }
+
+ string accountSid = settings.GetValueOrDefault(SystemSettings.TWILIO_ACCOUNTSID_KEY, string.Empty);
+ string authToken = settings.GetValueOrDefault(SystemSettings.TWILIO_AUTHTOKEN_KEY, string.Empty);
+ string phoneFrom = settings.GetValueOrDefault(SystemSettings.TWILIO_PHONEFROM_KEY, string.Empty);
+
+ if (string.IsNullOrEmpty(accountSid) || string.IsNullOrEmpty(accountSid) || string.IsNullOrEmpty(accountSid))
+ {
+ throw new Exception("Twilio settings are not set (System settings)");
+ }
+
+ var client = new TwilioRestClient(accountSid, authToken);
return client.SendSmsMessage(phoneFrom, to, body);
}
@@ -1726,7 +1737,8 @@ namespace WebsitePanel.EnterpriseServer
/// User Id
/// Reason why reset email is sent.
/// Optional, if null accountID user PrimaryEmailAddress will be used
- public static void SendResetUserPasswordEmail(int itemId, int accountId, string reason, string mailTo = null)
+ /// Url direction
+ public static void SendResetUserPasswordEmail(int itemId, int accountId, string reason, string mailTo, bool finalStep)
{
// load organization
Organization org = GetOrganization(itemId);
@@ -1753,16 +1765,16 @@ namespace WebsitePanel.EnterpriseServer
var logoUrl = generalSettings != null ? generalSettings.OrganizationLogoUrl : string.Empty;
- SendUserPasswordEmail(owner, user, reason, mailTo, logoUrl, UserSettings.USER_PASSWORD_RESET_LETTER, "USER_PASSWORD_RESET_LETTER");
+ SendUserPasswordEmail(owner, user, reason, mailTo, logoUrl, UserSettings.USER_PASSWORD_RESET_LETTER, "USER_PASSWORD_RESET_LETTER", finalStep);
}
public static void SendUserExpirationPasswordEmail(UserInfo owner, OrganizationUser user, string reason,
string mailTo, string logoUrl)
{
- SendUserPasswordEmail(owner, user, reason, user.PrimaryEmailAddress, logoUrl, UserSettings.USER_PASSWORD_EXPIRATION_LETTER, "USER_PASSWORD_EXPIRATION_LETTER");
+ SendUserPasswordEmail(owner, user, reason, user.PrimaryEmailAddress, logoUrl, UserSettings.USER_PASSWORD_EXPIRATION_LETTER, "USER_PASSWORD_EXPIRATION_LETTER", false);
}
- public static void SendUserPasswordEmail(UserInfo owner, OrganizationUser user, string reason, string mailTo, string logoUrl, string settingsName, string taskName)
+ public static void SendUserPasswordEmail(UserInfo owner, OrganizationUser user, string reason, string mailTo, string logoUrl, string settingsName, string taskName, bool finalStep)
{
UserSettings settings = UserController.GetUserSettings(owner.UserId,
settingsName);
@@ -1789,14 +1801,23 @@ namespace WebsitePanel.EnterpriseServer
priority = (MailPriority) Enum.Parse(typeof (MailPriority), settings["Priority"], true);
}
+ Guid token;
+
+ string pincode = finalStep ? GeneratePincode() : null;
+
Hashtable items = new Hashtable();
items["user"] = user;
items["logoUrl"] = logoUrl;
- items["passwordResetLink"] = GenerateUserPasswordResetLink(user.ItemId, user.AccountId);
+ items["passwordResetLink"] = GenerateUserPasswordResetLink(user.ItemId, user.AccountId, out token, pincode);
body = PackageController.EvaluateTemplate(body, items);
+ if (finalStep)
+ {
+ SetAccessTokenResponse(token, pincode);
+ }
+
TaskManager.Write("Organization ID : " + user.ItemId);
TaskManager.Write("Account : " + user.DisplayName);
TaskManager.Write("Reason : " + reason);
@@ -1837,14 +1858,15 @@ namespace WebsitePanel.EnterpriseServer
return SystemController.GetSystemSettingsInternal(SystemSettings.WEBDAV_PORTAL_SETTINGS, false);
}
- public static string GenerateUserPasswordResetLink(int itemId, int accountId)
+ public static string GenerateUserPasswordResetLink(int itemId, int accountId, out Guid tokenGuid, string pincode = null)
{
- string passwordResetUrlFormat = "account/password-reset/step-2";
+ string passwordResetUrlFormat = string.IsNullOrEmpty(pincode) ? "account/password-reset/step-2" : "account/password-reset/step-final";
var settings = GetWebDavSystemSettings();
if (settings == null || !settings.GetValueOrDefault(SystemSettings.WEBDAV_PASSWORD_RESET_ENABLED_KEY, false) ||!settings.Contains("WebdavPortalUrl"))
{
+ tokenGuid = new Guid();
return string.Empty;
}
@@ -1852,8 +1874,17 @@ namespace WebsitePanel.EnterpriseServer
var token = CreateAccessToken(itemId, accountId, AccessTokenTypes.PasswrodReset);
- return webdavPortalUrl.Append(passwordResetUrlFormat)
- .Append(token.AccessTokenGuid.ToString("n")).ToString();
+ tokenGuid = token.AccessTokenGuid;
+
+ var resultUrl = webdavPortalUrl.Append(passwordResetUrlFormat)
+ .Append(token.AccessTokenGuid.ToString("n"));
+
+ if (string.IsNullOrEmpty(pincode) == false)
+ {
+ resultUrl = resultUrl.Append(pincode);
+ }
+
+ return resultUrl.ToString();
}
private static AccessToken CreateAccessToken(int itemId, int accountId, AccessTokenTypes type)
diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/Web.config b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/Web.config
index fc4d3348..3a721fdd 100644
--- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/Web.config
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/Web.config
@@ -20,10 +20,6 @@
-
-
-
-
diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esOrganizations.asmx.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esOrganizations.asmx.cs
index 9ce4e663..ce6aa6f4 100644
--- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esOrganizations.asmx.cs
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esOrganizations.asmx.cs
@@ -356,9 +356,9 @@ namespace WebsitePanel.EnterpriseServer
}
[WebMethod]
- public void SendResetUserPasswordEmail(int itemId, int accountId, string reason, string mailTo = null)
+ public void SendResetUserPasswordEmail(int itemId, int accountId, string reason, string mailTo, bool finalStep)
{
- OrganizationController.SendResetUserPasswordEmail(itemId, accountId, reason, mailTo);
+ OrganizationController.SendResetUserPasswordEmail(itemId, accountId, reason, mailTo, finalStep);
}
#endregion
diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/RouteConfig.cs b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/RouteConfig.cs
index 98ab21f4..d26285c0 100644
--- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/RouteConfig.cs
+++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/RouteConfig.cs
@@ -38,14 +38,14 @@ namespace WebsitePanel.WebDavPortal
routes.MapRoute(
name: AccountRouteNames.PasswordResetSendSms,
- url: "account/password-reset/step-final/{token}",
+ url: "account/password-reset/send-new-sms/{token}",
defaults: new { controller = "Account", action = "PasswordResetSendSms" }
);
routes.MapRoute(
name: AccountRouteNames.PasswordResetFinalStep,
- url: "account/password-reset/send-new-sms/{token}",
- defaults: new { controller = "Account", action = "PasswordResetFinalStep" }
+ url: "account/password-reset/step-final/{token}/{pincode}",
+ defaults: new { controller = "Account", action = "PasswordResetFinalStep", pincode = UrlParameter.Optional }
);
routes.MapRoute(
diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/AccountController.cs b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/AccountController.cs
index 38b298db..776aef2e 100644
--- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/AccountController.cs
+++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/AccountController.cs
@@ -5,6 +5,7 @@ using System.Web.Mvc;
using System.Web.Routing;
using AutoMapper;
using log4net;
+using Microsoft.Web.Services3.Addressing;
using WebsitePanel.Providers.HostedSolution;
using WebsitePanel.WebDav.Core.Config;
using WebsitePanel.WebDav.Core.Security.Authentication;
@@ -186,7 +187,7 @@ namespace WebsitePanel.WebDavPortal.Controllers
return View(model);
}
- WspContext.Services.Organizations.SendResetUserPasswordEmail(exchangeAccount.ItemId, exchangeAccount.AccountId, Resources.Messages.PasswordResetUserReason, exchangeAccount.PrimaryEmailAddress);
+ WspContext.Services.Organizations.SendResetUserPasswordEmail(exchangeAccount.ItemId, exchangeAccount.AccountId, Resources.Messages.PasswordResetUserReason, exchangeAccount.PrimaryEmailAddress, false);
return View("PasswordResetEmailSent");
}
@@ -257,15 +258,16 @@ namespace WebsitePanel.WebDavPortal.Controllers
[HttpGet]
[AllowAnonymous]
- public ActionResult PasswordResetFinalStep(Guid token)
+ public ActionResult PasswordResetFinalStep(Guid token, string pincode)
{
- var smsResponse = Session[WebDavAppConfigManager.Instance.SessionKeys.PasswordResetSmsKey] as string;
+ var result = VerifyPincode(token, pincode);
- if (_smsAuthService.VerifyResponse(token, smsResponse) == false)
+ if (result != null)
{
- return RedirectToRoute(AccountRouteNames.PasswordResetSms);
+ return result;
}
+
var model = new PasswordEditor();
return View(model);
@@ -273,20 +275,18 @@ namespace WebsitePanel.WebDavPortal.Controllers
[HttpPost]
[AllowAnonymous]
- public ActionResult PasswordResetFinalStep(Guid token, PasswordEditor model)
+ public ActionResult PasswordResetFinalStep(Guid token, string pincode, PasswordEditor model)
{
if (!ModelState.IsValid)
{
return View(model);
}
- var smsResponse = Session[WebDavAppConfigManager.Instance.SessionKeys.PasswordResetSmsKey] as string;
+ var result = VerifyPincode(token, pincode);
- if (_smsAuthService.VerifyResponse(token, smsResponse) == false)
+ if (result != null)
{
- AddMessage(MessageType.Error, Resources.Messages.IncorrectSmsResponse);
-
- return RedirectToRoute(AccountRouteNames.PasswordResetSms);
+ return result;
}
var tokenEntity = WspContext.Services.Organizations.GetPasswordresetAccessToken(token);
@@ -333,6 +333,34 @@ namespace WebsitePanel.WebDavPortal.Controllers
#region Helpers
+ ///
+ /// Verify pincode, if it's absent - verifying pincode from session
+ ///
+ /// Password reset token
+ /// Pincode to verify if session pincode is absent
+ private ActionResult VerifyPincode(Guid token, string pincode)
+ {
+ var smsResponse = Session[WebDavAppConfigManager.Instance.SessionKeys.PasswordResetSmsKey] as string;
+
+ if (string.IsNullOrEmpty(pincode) == false)
+ {
+ smsResponse = pincode;
+ }
+
+ if (_smsAuthService.VerifyResponse(token, smsResponse) == false)
+ {
+ AddMessage(MessageType.Error, Resources.Messages.IncorrectSmsResponse);
+
+ return RedirectToRoute(AccountRouteNames.PasswordResetSms);
+ }
+
+ var tokenEntity = WspContext.Services.Organizations.GetPasswordresetAccessToken(token);
+
+ Session[WebDavAppConfigManager.Instance.SessionKeys.ItemId] = tokenEntity.ItemId;
+
+ return null;
+ }
+
private UserProfile GetUserProfileModel(int itemId, int accountId)
{
var user = WspContext.Services.Organizations.GetUserGeneralSettingsWithExtraData(itemId, accountId);
diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/App_LocalResources/SystemSettings.ascx.resx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/App_LocalResources/SystemSettings.ascx.resx
index 32b84ee8..050f293a 100644
--- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/App_LocalResources/SystemSettings.ascx.resx
+++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/App_LocalResources/SystemSettings.ascx.resx
@@ -180,4 +180,16 @@
Enable password reset:
+
+ AccountSID
+
+
+ AuthToken
+
+
+ Phone From
+
+
+ Twilio
+
\ No newline at end of file
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 6fc86dd2..8b5a315d 100644
--- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/OrganizationUserResetPassword.ascx.cs
+++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/OrganizationUserResetPassword.ascx.cs
@@ -39,7 +39,7 @@ namespace WebsitePanel.Portal.ExchangeServer
if (rbtnEmail.Checked)
{
- ES.Services.Organizations.SendResetUserPasswordEmail(PanelRequest.ItemID,PanelRequest.AccountID, txtReason.Text, txtEmailAddress.Text);
+ ES.Services.Organizations.SendResetUserPasswordEmail(PanelRequest.ItemID,PanelRequest.AccountID, txtReason.Text, txtEmailAddress.Text, true);
}
else
{
diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SystemSettings.ascx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SystemSettings.ascx
index a32574c2..83198973 100644
--- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SystemSettings.ascx
+++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SystemSettings.ascx
@@ -98,6 +98,24 @@
+
+
+
+
+
+
+ | |
+
+
+
+ | |
+
+
+
+ | |
+
+
+