From 9e154f22c417a6c51e458d081a04a27bcb6de922 Mon Sep 17 00:00:00 2001 From: Petr Hrehorovsky Date: Fri, 28 Jan 2022 11:08:30 +0100 Subject: [PATCH] FIX: Invalid tokens for password reset - token's purpose was Confirmation instead of ResetPassword --- backend/Origam.Security.Common/IManager.cs | 97 +++--- .../IdentityServiceAgent.cs | 2 +- .../AspNetManagerAdapter.cs | 295 +++++++++--------- .../Authorization/CoreManagerAdapter.cs | 7 +- 4 files changed, 202 insertions(+), 199 deletions(-) diff --git a/backend/Origam.Security.Common/IManager.cs b/backend/Origam.Security.Common/IManager.cs index 038dc98c26..0d11435e8f 100644 --- a/backend/Origam.Security.Common/IManager.cs +++ b/backend/Origam.Security.Common/IManager.cs @@ -1,49 +1,50 @@ -#region license -/* -Copyright 2005 - 2020 Advantage Solutions, s. r. o. - -This file is part of ORIGAM (http://www.origam.org). - -ORIGAM is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -ORIGAM is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with ORIGAM. If not, see . -*/ -#endregion -using System.Threading.Tasks; -using System.Xml; -using Origam.Security.Common; - -namespace Origam.Security.Identity -{ - public interface IManager - { - Task FindByNameAsync(string name); - Task ChangePasswordQuestionAndAnswerAsync(string userName, string password, string question, string answer); - Task IsLockedOutAsync(string userId); - Task GetTwoFactorEnabledAsync(string userId); - Task SetTwoFactorEnabledAsync(string userId, bool enabled); - Task IsEmailConfirmedAsync(string userId); - Task UnlockUserAsync(string userName); - Task ConfirmEmailAsync(string userId); - Task ConfirmEmailAsync(string userId, string token); - Task ChangePasswordAsync(string userId, string currentPassword, string newPassword); - Task ResetPasswordFromUsernameAsync(string userName, string token, string newPassword); - Task DeleteAsync(IOrigamUser user); - Task UpdateAsync(IOrigamUser user); - void SendNewUserToken(string userName); - Task CreateAsync(IOrigamUser user, string password); - Task GenerateEmailConfirmationTokenAsync(string userId); - Task GetPasswordResetTokenFromEmailAsync(string email); - Task GeneratePasswordResetTokenAsync1(string userId); - Task GetPasswordAttributesAsync(); - } +#region license +/* +Copyright 2005 - 2020 Advantage Solutions, s. r. o. + +This file is part of ORIGAM (http://www.origam.org). + +ORIGAM is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +ORIGAM is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with ORIGAM. If not, see . +*/ +#endregion + +using System.Threading.Tasks; +using System.Xml; +using Origam.Security.Common; + +namespace Origam.Security.Identity +{ + public interface IManager + { + Task FindByNameAsync(string name); + Task ChangePasswordQuestionAndAnswerAsync(string userName, string password, string question, string answer); + Task IsLockedOutAsync(string userId); + Task GetTwoFactorEnabledAsync(string userId); + Task SetTwoFactorEnabledAsync(string userId, bool enabled); + Task IsEmailConfirmedAsync(string userId); + Task UnlockUserAsync(string userName); + Task ConfirmEmailAsync(string userId); + Task ConfirmEmailAsync(string userId, string token); + Task ChangePasswordAsync(string userId, string currentPassword, string newPassword); + Task ResetPasswordFromUsernameAsync(string userName, string token, string newPassword); + Task DeleteAsync(IOrigamUser user); + Task UpdateAsync(IOrigamUser user); + void SendNewUserToken(string userName); + Task CreateAsync(IOrigamUser user, string password); + Task GenerateEmailConfirmationTokenAsync(string userId); + Task GetPasswordResetTokenFromEmailAsync(string email); + Task GeneratePasswordResetTokenAsync(string userId); + Task GetPasswordAttributesAsync(); + } } \ No newline at end of file diff --git a/backend/Origam.Security.Identity/IdentityServiceAgent.cs b/backend/Origam.Security.Identity/IdentityServiceAgent.cs index fb6853cd55..f5c378bdd7 100644 --- a/backend/Origam.Security.Identity/IdentityServiceAgent.cs +++ b/backend/Origam.Security.Identity/IdentityServiceAgent.cs @@ -706,7 +706,7 @@ private void GetPasswordResetToken() Resources.ErrorUserIdNotGuid); } Task task = userManager - .GeneratePasswordResetTokenAsync1( + .GeneratePasswordResetTokenAsync( Parameters["UserId"].ToString()); if (task.IsFaulted) { diff --git a/backend/Origam.Security.NetFx/AspNetManagerAdapter.cs b/backend/Origam.Security.NetFx/AspNetManagerAdapter.cs index ca8dac4c91..a4a30fce12 100644 --- a/backend/Origam.Security.NetFx/AspNetManagerAdapter.cs +++ b/backend/Origam.Security.NetFx/AspNetManagerAdapter.cs @@ -1,148 +1,149 @@ -#region license -/* -Copyright 2005 - 2020 Advantage Solutions, s. r. o. - -This file is part of ORIGAM (http://www.origam.org). - -ORIGAM is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -ORIGAM is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with ORIGAM. If not, see . -*/ -#endregion -using System.Threading.Tasks; -using System.Xml; -using Microsoft.AspNet.Identity; -using Origam.Security.Common; - -namespace Origam.Security.Identity -{ - public class AspNetManagerAdapter: IManager - { - private readonly AbstractUserManager aspNetUserManager; - - public AspNetManagerAdapter(AbstractUserManager aspNetUserManager) - { - this.aspNetUserManager = aspNetUserManager; - } - - public async Task FindByNameAsync(string name) - { - return await aspNetUserManager.FindByNameAsync(name); - } - - // - public async Task ChangePasswordQuestionAndAnswerAsync(string userName, string password, - string question, string answer) - { - return await aspNetUserManager.ChangePasswordQuestionAndAnswerAsync( - userName, password,question, answer); - } - - public async Task IsLockedOutAsync(string userId) - { - return await aspNetUserManager.IsLockedOutAsync(userId); - } - - public async Task GetTwoFactorEnabledAsync(string userId) - { - return await aspNetUserManager.GetTwoFactorEnabledAsync(userId); - } - - public async Task SetTwoFactorEnabledAsync(string userId, bool enabled) - { - return (await aspNetUserManager.SetTwoFactorEnabledAsync(userId, enabled)) - .Succeeded; - } - - public async Task IsEmailConfirmedAsync(string userId) - { - return await aspNetUserManager.IsEmailConfirmedAsync(userId); - } - - public async Task UnlockUserAsync(string userName) - { - return await aspNetUserManager.UnlockUserAsync(userName); - } - - public async Task ConfirmEmailAsync(string userId) - { - return (await aspNetUserManager.ConfirmEmailAsync(userId)) - .ToInternalIdentityResult(); - } - - public async Task ConfirmEmailAsync(string userId, string token) - { - return (await aspNetUserManager.ConfirmEmailAsync(userId, token)) - .ToInternalIdentityResult(); - } - - public async Task ChangePasswordAsync(string userId, string currentPassword, string newPassword) - { - return (await aspNetUserManager.ChangePasswordAsync(userId, currentPassword, - newPassword)) - .ToInternalIdentityResult(); - } - - public async Task ResetPasswordFromUsernameAsync(string userName, string token, string newPassword) - { - return (await aspNetUserManager.ResetPasswordFromUsernameAsync( - userName, token, newPassword)) - .ToInternalIdentityResult(); - } - - public async Task DeleteAsync(IOrigamUser user) - { - return (await aspNetUserManager.DeleteAsync((OrigamUser) user)) - .ToInternalIdentityResult(); - } - - public async Task UpdateAsync(IOrigamUser user) - { - return (await aspNetUserManager.UpdateAsync((OrigamUser)user)) - .ToInternalIdentityResult(); - } - - public void SendNewUserToken(string userName) - { - aspNetUserManager.SendNewUserToken(userName); - } - - public async Task CreateAsync(IOrigamUser user, string password) - { - return (await aspNetUserManager.CreateAsync((OrigamUser) user, - password)).ToInternalIdentityResult(); - } - - public async Task GenerateEmailConfirmationTokenAsync(string userId) - { - return await aspNetUserManager.GenerateEmailConfirmationTokenAsync( - userId); - } - - public async Task GetPasswordResetTokenFromEmailAsync(string email) - { - return await aspNetUserManager - .GetPasswordResetTokenFromEmailAsync(email); - } - - public async Task GeneratePasswordResetTokenAsync1(string userId) - { - return await aspNetUserManager.GeneratePasswordResetTokenAsync( - userId); - } - - public async Task GetPasswordAttributesAsync() - { - return await aspNetUserManager.GetPasswordAttributesAsync(); - } - } +#region license +/* +Copyright 2005 - 2020 Advantage Solutions, s. r. o. + +This file is part of ORIGAM (http://www.origam.org). + +ORIGAM is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +ORIGAM is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with ORIGAM. If not, see . +*/ +#endregion + +using System.Threading.Tasks; +using System.Xml; +using Microsoft.AspNet.Identity; +using Origam.Security.Common; + +namespace Origam.Security.Identity +{ + public class AspNetManagerAdapter: IManager + { + private readonly AbstractUserManager aspNetUserManager; + + public AspNetManagerAdapter(AbstractUserManager aspNetUserManager) + { + this.aspNetUserManager = aspNetUserManager; + } + + public async Task FindByNameAsync(string name) + { + return await aspNetUserManager.FindByNameAsync(name); + } + + // + public async Task ChangePasswordQuestionAndAnswerAsync(string userName, string password, + string question, string answer) + { + return await aspNetUserManager.ChangePasswordQuestionAndAnswerAsync( + userName, password,question, answer); + } + + public async Task IsLockedOutAsync(string userId) + { + return await aspNetUserManager.IsLockedOutAsync(userId); + } + + public async Task GetTwoFactorEnabledAsync(string userId) + { + return await aspNetUserManager.GetTwoFactorEnabledAsync(userId); + } + + public async Task SetTwoFactorEnabledAsync(string userId, bool enabled) + { + return (await aspNetUserManager.SetTwoFactorEnabledAsync(userId, enabled)) + .Succeeded; + } + + public async Task IsEmailConfirmedAsync(string userId) + { + return await aspNetUserManager.IsEmailConfirmedAsync(userId); + } + + public async Task UnlockUserAsync(string userName) + { + return await aspNetUserManager.UnlockUserAsync(userName); + } + + public async Task ConfirmEmailAsync(string userId) + { + return (await aspNetUserManager.ConfirmEmailAsync(userId)) + .ToInternalIdentityResult(); + } + + public async Task ConfirmEmailAsync(string userId, string token) + { + return (await aspNetUserManager.ConfirmEmailAsync(userId, token)) + .ToInternalIdentityResult(); + } + + public async Task ChangePasswordAsync(string userId, string currentPassword, string newPassword) + { + return (await aspNetUserManager.ChangePasswordAsync(userId, currentPassword, + newPassword)) + .ToInternalIdentityResult(); + } + + public async Task ResetPasswordFromUsernameAsync(string userName, string token, string newPassword) + { + return (await aspNetUserManager.ResetPasswordFromUsernameAsync( + userName, token, newPassword)) + .ToInternalIdentityResult(); + } + + public async Task DeleteAsync(IOrigamUser user) + { + return (await aspNetUserManager.DeleteAsync((OrigamUser) user)) + .ToInternalIdentityResult(); + } + + public async Task UpdateAsync(IOrigamUser user) + { + return (await aspNetUserManager.UpdateAsync((OrigamUser)user)) + .ToInternalIdentityResult(); + } + + public void SendNewUserToken(string userName) + { + aspNetUserManager.SendNewUserToken(userName); + } + + public async Task CreateAsync(IOrigamUser user, string password) + { + return (await aspNetUserManager.CreateAsync((OrigamUser) user, + password)).ToInternalIdentityResult(); + } + + public async Task GenerateEmailConfirmationTokenAsync(string userId) + { + return await aspNetUserManager.GenerateEmailConfirmationTokenAsync( + userId); + } + + public async Task GetPasswordResetTokenFromEmailAsync(string email) + { + return await aspNetUserManager + .GetPasswordResetTokenFromEmailAsync(email); + } + + public async Task GeneratePasswordResetTokenAsync(string userId) + { + return await aspNetUserManager.GeneratePasswordResetTokenAsync( + userId); + } + + public async Task GetPasswordAttributesAsync() + { + return await aspNetUserManager.GetPasswordAttributesAsync(); + } + } } \ No newline at end of file diff --git a/backend/Origam.ServerCore/Authorization/CoreManagerAdapter.cs b/backend/Origam.ServerCore/Authorization/CoreManagerAdapter.cs index c8f13c906d..30aa8a2c45 100644 --- a/backend/Origam.ServerCore/Authorization/CoreManagerAdapter.cs +++ b/backend/Origam.ServerCore/Authorization/CoreManagerAdapter.cs @@ -194,7 +194,7 @@ public async Task GetPasswordResetTokenFromEmailAsync(string email) TokenValidityHours = 0}; } - string token = await GenerateEmailConfirmationTokenAsync(user.BusinessPartnerId); + string token = await GeneratePasswordResetTokenAsync(user.BusinessPartnerId); return new TokenResult { Token = token, @@ -202,9 +202,10 @@ public async Task GetPasswordResetTokenFromEmailAsync(string email) TokenValidityHours = 24}; } - public async Task GeneratePasswordResetTokenAsync1(string userId) + public async Task GeneratePasswordResetTokenAsync(string userId) { - return await GenerateEmailConfirmationTokenAsync(userId); + var user = await FindByIdAsync(userId); + return await coreUserManager.GeneratePasswordResetTokenAsync(user); } public Task GetPasswordAttributesAsync()