/// <summary> /// Change password for the user. /// </summary> /// <param name="request">The device activation request.</param> /// <returns>The device activation response.</returns> private static StaffChangePasswordRealtimeResponse ChangePassword(UserChangePasswordRealtimeRequest request) { string staffId = request.StaffId; if (string.IsNullOrWhiteSpace(staffId)) { throw new UserAuthorizationException(SecurityErrors.Microsoft_Dynamics_Commerce_Runtime_ChangePasswordFailed, "Staff Id is not valid."); } TransactionService.TransactionServiceClient transactionService = new TransactionService.TransactionServiceClient(request.RequestContext); string newPasswordHash; string newPasswordSalt; string newPasswordHashAlgorithm; DateTimeOffset newPasswordLastChangedDateTime; AuthenticationOperation newPasswordLastUpdatedOperation; transactionService.StaffChangePassword( staffId, request.OldPassword, request.NewPassword, changePassword: false, newPasswordHash: out newPasswordHash, newPasswordSalt: out newPasswordSalt, newPasswordHashAlgorithm: out newPasswordHashAlgorithm, newPasswordLastChangedDateTime: out newPasswordLastChangedDateTime, newPasswordLastUpdatedOperation: out newPasswordLastUpdatedOperation); return(new StaffChangePasswordRealtimeResponse(newPasswordHash, newPasswordSalt, newPasswordHashAlgorithm, newPasswordLastChangedDateTime, newPasswordLastUpdatedOperation)); }
/// <summary> /// Change password for the user. /// </summary> /// <param name="request">The device activation request.</param> /// <returns>The device activation response.</returns> private static Response ChangePassword(UserChangePasswordRealtimeRequest request) { ThrowIf.Null(request, "request"); long channelId = request.RequestContext.GetPrincipal().ChannelId; string staffId = request.StaffId; // Get employee salt and password hash algorithm. GetEmployeePasswordCryptoInfoDataRequest employeePasswordCryptoInfoRequest = new GetEmployeePasswordCryptoInfoDataRequest(channelId, staffId); var passwordCryptoInfo = request.RequestContext.Execute <SingleEntityDataServiceResponse <EmployeePasswordCryptoInfo> >(employeePasswordCryptoInfoRequest).Entity; string salt = passwordCryptoInfo.PasswordSalt ?? string.Empty; string passwordHashAlgorithm = passwordCryptoInfo.PasswordHashAlgorithm; if (string.IsNullOrEmpty(passwordHashAlgorithm)) { // get hash algorithm from the transaction service profile. var getTransactionServiceProfileDataRequest = new GetTransactionServiceProfileDataRequest(); TransactionServiceProfile transactionServiceProfile = request.RequestContext.Execute <SingleEntityDataServiceResponse <TransactionServiceProfile> >( getTransactionServiceProfileDataRequest).Entity; passwordHashAlgorithm = transactionServiceProfile.StaffPasswordHash; } // hash old password HashDataServiceRequest hashDataServiceRequest = new HashDataServiceRequest(request.OldPassword, passwordHashAlgorithm, request.StaffId, salt); string oldPasswordHash = request.RequestContext.Execute <HashDataServiceResponse>(hashDataServiceRequest).Data; // check if old password is correct EmployeeLogOnStoreDataRequest employeeDataRequest = new EmployeeLogOnStoreDataRequest( channelId, staffId, oldPasswordHash, new ColumnSet()); if (request.RequestContext.Execute <SingleEntityDataServiceResponse <Employee> >(employeeDataRequest).Entity == null) { // SecurityErrors.Microsoft_Dynamics_Commerce_Runtime_InvalidPassword is used internally to identify when user provides incorrect password // here we make sure this is not surfaced outside of the runtime, so there is no information disclosure throw new UserAuthenticationException(SecurityErrors.Microsoft_Dynamics_Commerce_Runtime_InvalidAuthenticationCredentials, "Incorrect user name or password."); } // hash new password hashDataServiceRequest = new HashDataServiceRequest(request.NewPassword, passwordHashAlgorithm, request.StaffId, salt); string newPasswordHash = request.RequestContext.Execute <HashDataServiceResponse>(hashDataServiceRequest).Data; // return new password hash + salt return(new StaffChangePasswordRealtimeResponse(newPasswordHash, salt, passwordHashAlgorithm, DateTime.UtcNow, AuthenticationOperation.ChangePassword)); }