Open Closed

How to prevent "admin@abp.io" admin user seeding ? #894


User avatar
1
selinkoykiran created

Hello, To prevent inserting abp default admin user we override IdentityDataSeeder and IdentityDataSeedContributor Seed methods. But IdentityDataSeeder method called 2 times in debug mode . At first time method came with admin@abp.io email information and second time our overridden admin definition inserted. But we don't want to add abp default admin user when seeding. What do we need to do ? We made if else for now but we don't want to use like below. Thank you .

  • ABP Framework version: v4.1.2
  • UI type: MVC
  • DB provider: EF Core
  • **Tiered (MVC): yes
  • Exception message and stack trace:
  • Steps to reproduce the issue:

4 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi @selinkoykiran

    Can you share your full code?

  • User Avatar
    0
    alper created
    Support Team Director

    if you send us your customized classes we'll try to reproduce

  • User Avatar
    0
    selinkoykiran created

    Hello, In my domain module I add CustomIdentityDataSeeder and CustomIdentityDataSeedContributor classes like below. In the note section we described the situation. Because of dependency injection issues maybe this class hits 2 times . At first time admin email comes with admin@abp.io email second time I could use my custom email . But how does it admin@abp.io default email hit at the first time. How could I prevent it because I think I've already overriden these classes . I don't want to check like if blocks.

    Thank you

    CustomIdentityDataSeedContributor

    using System.Threading.Tasks;
    using Volo.Abp.Data;
    using Volo.Abp.Identity;
    namespace Custom.XXX.Identity
    {
        public class CustomIdentityDataSeedContributor :  IdentityDataSeedContributor
        {
            protected CustomIdentityDataSeeder CustomIdentityDataSeeder { get; }
    
            public CustomIdentityDataSeedContributor(CustomIdentityDataSeeder identityDataSeeder) 
                : base(identityDataSeeder)
            {
                CustomIdentityDataSeeder = identityDataSeeder;
            }
    
            public override Task SeedAsync(DataSeedContext context)
            {
                return CustomIdentityDataSeeder.SeedAsync(
                   "custom@Custom.com",
                   "Pass1234+",
                   context?.TenantId
               );
    
            }
        }
    }
    
    

    CustomIdentityDataSeeder

    using Microsoft.AspNetCore.Identity;
    using Microsoft.Extensions.Options;
    using System;
    using System.Threading.Tasks;
    using Volo.Abp;
    using Volo.Abp.Guids;
    using Volo.Abp.Identity;
    using Volo.Abp.MultiTenancy;
    using Volo.Abp.Uow;
    using IdentityRole = Volo.Abp.Identity.IdentityRole;
    using IdentityUser = Volo.Abp.Identity.IdentityUser;
    
    namespace Custom.XXX.Identity
    {
        public class CustomIdentityDataSeeder : IdentityDataSeeder
        {
            public CustomIdentityDataSeeder(IGuidGenerator guidGenerator,
                IIdentityRoleRepository roleRepository,
                IIdentityUserRepository userRepository,
                ILookupNormalizer lookupNormalizer,
                IdentityUserManager userManager,
                IdentityRoleManager roleManager,
                ICurrentTenant currentTenant,
                IOptions<IdentityOptions> identityOptions)
                : base(guidGenerator, roleRepository, userRepository, lookupNormalizer, userManager, roleManager, currentTenant, identityOptions)
            {
            }
    
            [UnitOfWork]
            public override async Task<IdentityDataSeedResult> SeedAsync(string adminEmail, string adminPassword, Guid? tenantId = null)
            {
                var result = new IdentityDataSeedResult();
                Check.NotNullOrWhiteSpace(adminEmail, nameof(adminEmail));
                Check.NotNullOrWhiteSpace(adminPassword, nameof(adminPassword));
                string adminUserName = "custom";
    		**	//NOTE  we dont want to check like below for abp.io user 
                if (adminEmail == "admin@abp.io")
                {
                    return result;
                }**
                if (tenantId!= Guid.Empty && tenantId != null)
                {
                    adminUserName = "custom2";
                    if(adminEmail == "custom@Custom.com")
                    {
                        adminEmail = "custom2@Custom.com";
                    }
                }
    
                using (CurrentTenant.Change(tenantId))
                {
                    //"admin" user
                   
                    var adminUser = await UserRepository.FindByNormalizedUserNameAsync(
                        LookupNormalizer.NormalizeName(adminUserName)
                    );
    
                    if (adminUser != null)
                    {
                        return result;
                    }
    
                    adminUser = new IdentityUser(
                        GuidGenerator.Create(),
                        adminUserName,
                        adminEmail,
                        tenantId
                    )
                    {
                        Name = adminUserName
                    };
    
                    (await UserManager.CreateAsync(adminUser, adminPassword)).CheckErrors();
                    result.CreatedAdminUser = true;
    
                    //"admin" role
                    const string adminRoleName = "admin";
                    var adminRole = await RoleRepository.FindByNormalizedNameAsync(LookupNormalizer.NormalizeName(adminRoleName));
                    if (adminRole == null)
                    {
                        adminRole = new IdentityRole(
                            GuidGenerator.Create(),
                            adminRoleName,
                            tenantId
                        )
                        {
                            IsStatic = true,
                            IsPublic = true
                        };
    
                        (await RoleManager.CreateAsync(adminRole)).CheckErrors();
                        result.CreatedAdminRole = true;
                    }
    
                    (await UserManager.AddToRoleAsync(adminUser, adminRoleName)).CheckErrors();
    
                    return result;
                }
            }
        }
    }
    
    
  • User Avatar
    2
    hikalkan created
    Support Team Co-Founder

    This problem occurs since you are registering a second data seed contributor but not removing or replacing the original one.

    Actually, you don't have to replace it just set admin email/password. Open MyProjectNameDbMigrationService in your solution, find the SeedDataAsync method, find this line:

    await _dataSeeder.SeedAsync(tenant?.Id);
    

    Change it like:

    await _dataSeeder.SeedAsync(
    	new DataSeedContext(tenant?.Id)
    		.WithProperty("AdminEmail", "...........")
    		.WithProperty("AdminPassword", "..............")
    	);
    

    I believe we should add this to the startup template, so it will be easy to understand it.

    BTW, if you want to override a service, you should replace it as documented: https://docs.abp.io/en/abp/latest/Dependency-Injection#replace-a-service

Made with ❤️ on ABP v8.2.0-preview Updated on March 25, 2024, 15:11