Base solution for your next web application
Open Closed

Password Field Is Required #3979


User avatar
0
devkev2403 created

I can not save users in the admin back office (for example, I can not assign roles). When I try to save a user I get a pop up error message.

The modal does indeed call the UserAppService - CreateOrUpdateUser

This error is written to the log file:

ERROR 2017-10-03 16:50:06,694 [44 ] ud.EntityFramework.UtilityCloudDbContext - There are some validation errors while saving changes in EntityFramework: ERROR 2017-10-03 16:50:06,694 [44 ] ud.EntityFramework.UtilityCloudDbContext - - Password: The Password field is required.

Is this a bug that has since been fixed?


16 Answer(s)
  • User Avatar
    0
    devkev2403 created

    Perhaps a better way to phrase my question.

    In order to change a users roles using ABP Zero, I have to change the password at the same time. I just want to be able to change the assigned roles without changing the password. Is this possible?

  • User Avatar
    0
    devkev2403 created

    I have fixed this by editting the UserAppService, method UpdateUserAsync. But I can't help thinking I am missing something and I didn't need to change such a fundamental part of the system. Here is my change - I welcome any comments.

    [AbpAuthorize(AppPermissions.Pages_Administration_Users_Edit)]
            protected virtual async Task UpdateUserAsync(CreateOrUpdateUserInput input)
            {
                Debug.Assert(input.User.Id != null, "input.User.Id should be set.");
    
                var user = await UserManager.FindByIdAsync(input.User.Id.Value);
    
    //////// THIS VARIABLE IS NEW
                var originalPassword = user.Password;
    
                //Update user properties
                input.User.MapTo(user); //Passwords is not mapped (see mapping configuration)
                
                if (input.SetRandomPassword)
                {
                    input.User.Password = User.CreateRandomPassword();
                }
    //////// THE 'ELSE' KEYWORD IS NEW
                else if (!input.User.Password.IsNullOrEmpty())
                {
                    CheckErrors(await UserManager.ChangePasswordAsync(user, input.User.Password));
                }
    //////// THIS ELSE BLOCK IS NEW
                else
                {
                    user.Password = originalPassword;
                }
    
                CheckErrors(await UserManager.UpdateAsync(user));
    
                //Update roles
                CheckErrors(await UserManager.SetRoles(user, input.AssignedRoleNames));
    
                if (input.SendActivationEmail)
                {
                    user.SetNewEmailConfirmationCode();
                    await _userEmailer.SendEmailActivationLinkAsync(user, input.User.Password);
                }
            }
    
  • User Avatar
    0
    aaron created
    Support Team

    Can you check if replacing input.User.MapTo(user) with ObjectMapper.Map(input.User, user) solves this issue? Mapping configuration is in src/MyCompanyName.AbpZeroTemplate.Application/CustomDtoMapper.cs#L29-L32.

  • User Avatar
    0
    devkev2403 created

    HI Arron,

    thank you for your reply, but unfortunately your suggestion does not work.

    If I only change the roles a user belongs to, the form input data that is sent to the user service does not contain a password (the password is an empty string). Therefore, even though using the ObjectMapper.Map function will map the password field, it maps the empty string, and so the EntityFramework update fails.

  • User Avatar
    0
    aaron created
    Support Team

    It will not map the password. Did you try?

  • User Avatar
    0
    devkev2403 created

    HI Arron,

    yes I tried it in my debugger. Using your method does map the password. I will double check now though.

  • User Avatar
    0
    devkev2403 created

    It definitely maps. Here is my current code for reference:

    protected virtual async Task UpdateUserAsync(CreateOrUpdateUserInput input)
            {
                Debug.Assert(input.User.Id != null, "input.User.Id should be set.");
    
                var user = await UserManager.FindByIdAsync(input.User.Id.Value);
    
                //var originalPassword = user.Password;
    
                //Update user properties
                //input.User.MapTo(user); //Passwords is not mapped (see mapping configuration)
    
    ////////// PROVIDE A FAKE PASSWORD AND SEE IF IT MAPS
                input.User.Password = "ThisIsFake-WillItMap";
    
    //////////CODE SUGGESTED BY ARRON
                ObjectMapper.Map(input.User, user);
    
    //////////BREAKPOINT HERE AND REVIEW
                Debug.Assert(user.Password.Equals(input.User.Password), "Password did not map.");
    
                if (input.SetRandomPassword)
                {
                    input.User.Password = User.CreateRandomPassword();
                }
                if (!input.User.Password.IsNullOrEmpty())
                {
                    CheckErrors(await UserManager.ChangePasswordAsync(user, input.User.Password));
                }
                //else
                //{
                //    user.Password = originalPassword;
                //}
    
                CheckErrors(await UserManager.UpdateAsync(user));
    
                //Update roles
                CheckErrors(await UserManager.SetRoles(user, input.AssignedRoleNames));
    
                if (input.SendActivationEmail)
                {
                    user.SetNewEmailConfirmationCode();
                    await _userEmailer.SendEmailActivationLinkAsync(user, input.User.Password);
                }
            }
    
  • User Avatar
    0
    aaron created
    Support Team

    Can you put a breakpoint in CustomDtoMapper to see if the configuration is run?

  • User Avatar
    0
    devkev2403 created

    The CustomDtoMapper does not appear to be executed.

  • User Avatar
    0
    aaron created
    Support Team

    If you change internal to public, does it run?

  • User Avatar
    0
    devkev2403 created

    Apologies, it is executed. The debugger does not hit the break points but I have added some log statements and these get written to the log file. For example:

    DEBUG 2017-10-04 15:46:06,130 [25 ] CustomDtoMapper - Entered method CreateMappingsInternal

  • User Avatar
    0
    ismcagdas created
    Support Team

    @devkev2403 have you solved the problem ?

  • User Avatar
    0
    devkev2403 created

    The problem is solved if I use this editted code. Is this a bug or am I doing something wrong?

    [AbpAuthorize(AppPermissions.Pages_Administration_Users_Edit)]
    protected virtual async Task UpdateUserAsync(CreateOrUpdateUserInput input)
    {
        Debug.Assert(input.User.Id != null, "input.User.Id should be set.");
    
        var user = await UserManager.FindByIdAsync(input.User.Id.Value);
    
    //////// THIS VARIABLE IS NEW
        var originalPassword = user.Password;
    
        //Update user properties
        input.User.MapTo(user); //Passwords is not mapped (see mapping configuration)
                
        if (input.SetRandomPassword)
        {
            input.User.Password = User.CreateRandomPassword();
        }
    //////// THE 'ELSE' KEYWORD IS NEW
        else if (!input.User.Password.IsNullOrEmpty())
        {
            CheckErrors(await UserManager.ChangePasswordAsync(user, input.User.Password));
        }
    //////// THIS ELSE BLOCK IS NEW
        else
        {
            user.Password = originalPassword;
        }
    
        CheckErrors(await UserManager.UpdateAsync(user));
    
        //Update roles
        CheckErrors(await UserManager.SetRoles(user, input.AssignedRoleNames));
    
        if (input.SendActivationEmail)
        {
            user.SetNewEmailConfirmationCode();
            await _userEmailer.SendEmailActivationLinkAsync(user, input.User.Password);
        }
    }
    
  • User Avatar
    0
    aaron created
    Support Team

    Your modification is fine. Which version of the MVC 5.x template are you using?

  • User Avatar
    0
    devkev2403 created

    Hi Aaron,

    this only seems to be a problem on .NET Core v3.0.0.0. The code fix I suggested is not needed on on the MVC 5.x version bt the UserAppService code looks the same (2 minor differences on .NET core version).

  • User Avatar
    0
    aaron created
    Support Team

    Oh, it looked like you were using the MVC 5.x version as your UserAppService was not up-to-date. Can you try a fresh template (which should work) and if it works, update the files in your project?